1

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

我有一个实例objectAobjectB以下类:

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

objectA是空的。objectB设置了值。在应用程序的某个点,我只想丢弃objectB和离开objectA,所以我需要注入这两个值objectBto 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");
}];
4

1 回答 1

1

除了我评论中的问题之外,这可能无论如何都不起作用。

块不仅是一段代码,而且是闭包。这意味着他们会对创建的时间点进行快照。如果这样的块objectB在创建时引用,则在复制后它们仍将引用该对象,即使您将块或其副本存储到objectA. (实例对象没有标识符,但是,我想我明白你的意思。)

所以,有这个代码:

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

会做一些事情objectB。复制后(此处明确)……</p>

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

......它仍然是一样的:将完成一些事情objectB,因为它仍然被块引用。

于 2016-04-04T17:13:03.057 回答