2016-04-04 5 views
1

私はいつも考えていた、copyは、オブジェクトをコピーするだけです。ブロックの場合は少し違っていますが、私は実際にそれがどのように動作するのか驚いています。オブジェクト間のブロックのコピー

私が持っていると、インスタンスobjectAと以下のクラスのobjectB

@interface MyObject : NSObject 
@property(nonatomic, copy) void (^myHandler)(CGFloat progress); 
@property(nonatomic) CGFloat progress; 
@end 

objectAは空です。 objectBには値が設定されています。アプリのいくつかの点では、私はobjectBを破棄し、唯一objectAを残したいので、私はobjectAobjectBのこれら2つの値を挿入する必要があります。

MyObject *objectA = [MyObject new]; 
if (nowIWantToGetRidOfB) { 
    objectA.progress = objectB.progress; 
    objectA.myHandler = objectB.myHandler; 
    objectB.myHandler = nil; 
    objectB = nil; // that's just an example to show it gets released after this code 
} 

私はブロックが新しいobjectAインスタンスにコピーすることを期待したいですobjectBが解放されます(参照先がないため)。

代わりに何も起こりません。そのブロックは、たとえそれが再び評価されることはありません。別の方法でそれをコピーする必要がありますか?誰かが何が起こっているのかを説明することができますか、それを説明するいくつかの文書を指摘できますか?

- 編集 - ブロックが設定されている方法

スニペット:私のコメントに質問横

MyObject *objectB = [MyObject new]; 
objectB.progress = 0.5f; 
[objectB setProgressHandler:^(CGFloat progress) { 
    NSLog(@"example"); 
}]; 
+0

'objectA'の' myHandler'プロパティを使用するコードで質問を更新してください。 – rmaddy

+0

オブジェクトにブロックを使用しないでください。 javascriptから客観的になる開発者の悪い習慣です。あなたの場合、 'delegate'が必要です。ブロックは、非同期メソッドのコールバックとしてのみ使用する必要があります。 –

+0

ハンドラがどのように使用されているかを見ることができるように、ハンドラを作成/割り当てるコードをobjectBに表示できますか? –

答えて

1

、これはおそらくとにかく動作しません。

ブロックはコードのスニペットではなく、クロージャです。つまり、作成された時点のスナップショットを実行します。そのようなブロックが作成時にobjectBを参照する場合、コピー後にブロックまたはそのコピーをobjectAに保存したとしても、コピー後もそのオブジェクトを参照します。 (インスタンスオブジェクトは、しかし、私はあなたが何を意味するかを理解すると思うが、識別子を持っていません。)だから、

を、このコードを持つ:

MyObject *objectB = …; 
objectB.handler = ^(CGFloat progress) 
{ 
    … objectB … 
} 

何かがobjectBで行われます。 ...(ここでは明示的に)

MyObject *objectA = …; 
objectA.handler = objectB.handler; 

をコピーした後...それはまだ同じである:それはまだブロックで言及されているので何かは、objectBで行われます。

+0

ブロック内に単純なNSLogを置いていても、 'objectB'を使用しないので、私が記述した方法を終了しました。私はオブジェクト全体をブロックで置き換えるだけで完了し、それは完全に機能しています。 – Vive

+0

はい、あなたの編集でそれを見ました。 –

関連する問題