在对象之间复制块

时间:2016-04-04 15:24:38

标签: objective-c objective-c-blocks nscopying

我一直认为,copy只会复制该对象。在块的情况下,它有点不同,但我真的很惊讶它在以下情况下如何工作。

我有以下类的实例objectAobjectB

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

objectA为空。 objectB已设置值。在应用的某些方面,我想放弃objectB并仅保留objectA,因此我需要将objectB的这两个值注入objectA

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");
}];

1 个答案:

答案 0 :(得分:1)

Beside the question in my comment, this likely does not work anyway.

Blocks are not only a snippet of code, but closures. That means that they do a snapshot of the point in time they are created. If such a block refers to objectB at creation time, after copying they will still refer to that object, even you store the block or a copy of it to objectA. (Instance objects does not have identifiers, however, I think I understand what you mean.)

So, having this code:

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

Something will be done with objectB. After copying (here explicitly) …

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

… it is still the same: Something will be done with objectB, because it is still referred by the block.