【发布时间】:2015-11-09 19:23:42
【问题描述】:
在 Objective-C 中,您可能希望在块内使用实例变量,并将该块存储在对象本身中。如果你这样做,你会遇到相当麻烦的事情,以确保你不创建循环依赖,并消除所有编译器警告:
@implementation TestBlock {
int someVariable;
void (^someBlock)();
}
- (void) createBlock
{
// ideally I would like to use:
someBlock = ^{
someVariable++;
};
// but in reality I need to use:
TestBlock * __weak weakSelf = self;
someBlock = ^{
TestBlock *strongSelf = weakSelf;
strongSelf->someVariable++;
};
}
@end
如果使用weakSelf,而不是strongSelf,那么你会得到错误:
不允许取消引用 __weak 指针
如果直接使用self,则会创建一个保留循环。
我知道为什么需要这样做的背景,但是真的没有更简单的方法可以在块中使用实例变量吗?有什么实用的方法可以使这个更短、更易读吗?
【问题讨论】:
-
您没有其他选项可以直接访问 ivar。但是您可以选择使用 ivar 周围的属性。然后您可以使用
wealSelf访问该属性。 -
如果你必须访问 ivar,你可以使用“@weakify”和“@strongify”宏holko.pl/2015/05/31/weakify-strongify>,这使它更具可读性。
-
关键是要避免块作为 ivars。例如,您可以重新设计您的类,使其具有接受块作为参数的方法。
-
@ReinhardMänner 我不知道你提到的weakify-strongify 宏,这是一个有趣的想法,我一定会尝试。至少它使发生的事情更加简洁明了。
-
@CouchDeveloper 像我在示例中显示的那样将块作为直接实例变量确实很少见。但是很常见的 iVar 带有另一个类的对象,它包含您提供给它的块。这将构成完全相同的问题。
标签: objective-c objective-c-blocks instance-variables weak-references