【发布时间】:2014-12-09 12:48:00
【问题描述】:
如标题所述,在 ARC 模式下,当我使用自引用定义块时(弱以避免引用循环):
...
id __weak weakSelf = self;
self.someBlock = ^(){
if (weakSelf != nil){
(do something with weakSelf...)
return NO;
}
return YES;
};
...
在 dealloc 中我调用了块:
- (void)dealloc {
...
BOOL isNil = self.someBlock();
...
}
然后我发现isNil = YES。
当我想让 dealloc 中的块对 self 做某事时,这似乎是个问题。
回调函数中也会出现这种情况,这里我就不举例了。
我的解决方案是使用 __unsafe_unretained 而不是 __weak。
但这看起来很难看。
有没有更好的方法来避免在 dealloc 中出现 nil weak self ?
更新的问题:为什么weakSelf 是无效的,即使self 不是?是dealloc的原因吗?
为了清楚起见,我把测试代码贴在下面:
#import <Foundation/Foundation.h>
@interface blockWeak : NSObject
@property (nonatomic, strong) BOOL (^someBlock)();
@property (nonatomic) int num;
- (void)makeBlock;
@end
@implementation blockWeak
- (void)makeBlock
{
typeof(self) __weak weakSelf = self;
self.someBlock = ^(){
typeof(self) strongSelf = weakSelf;
strongSelf.num = 2;
return weakSelf == nil?YES:NO;
};
}
- (void)dealloc
{
BOOL isNil = self.someBlock();
if (isNil) {
NSLog(@"weakSelf is nil.");
}
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
blockWeak *bw = [[blockWeak alloc] init];
bw.num = 1;
[bw makeBlock];
}
return 0;
}
【问题讨论】:
-
除了答案中提到的明显错误之外,您的用例是什么?检查
weakSelf是否已经在dealloc中被取消似乎不是您应该做的事情。 -
真正的用例是,我需要块做一些清理工作,而不是在 dealloc 中释放内存,这可能会使用类的属性/ivars,甚至是 self。我稍微修改一下问题以使其更清楚。
-
你可以在 dealloc 中调用任何东西,甚至使用 self。
-
我试过了。使用 self 是可以的。我将块上的代码复制到 dealloc 并且它可以工作。但是,当您在 dealloc 中使用包含指向 self 的弱指针的块/函数时,它不起作用,因为当程序进入块/函数内部时,“weakSelf”变为 nil。这就是我感到困惑的原因。
标签: ios objective-c automatic-ref-counting