使用ARC
test1:
@interface test01ViewController ()
@property (strong) void(^myBlock)(id obj, NSUInteger idx, BOOL stop);
@end
@implementation test01ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.navigationItem.title = @"test01";
[self setMyBlock:^(id obj, NSUInteger idx, BOOL stop) {
[self doSomethingWithObj:obj];
}];
}
object(self
)具有对该块的显式强引用。并且该块具有对strong
的隐式self
引用。这是一个周期,现在两个对象都不会被正确释放。
所以test1 dealloc
不打电话。
test2:
@interface test03ViewController ()
@property (strong) void(^myBlock)(id obj, NSUInteger idx, BOOL stop);
@end
@implementation test03ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.navigationItem.title = @"test03";
__weak test03ViewController *weakSelf = self;
[self setMyBlock:^(id obj, NSUInteger idx, BOOL stop) {
__strong test03ViewController *strongSelf = weakSelf;
[strongSelf doSomethingWithObj:obj];
}];
}
__ weakSelf-> __strongSelf,我认为它与test1
没什么区别,但是test2可以调用dealloc
。
为什么?
看看这个答案:https://stackoverflow.com/a/28475562/543224
无论如何,关于这种模式,获取强大的引用对于在块运行之前自我被释放的情况没有任何作用,这仍然可能发生。它确实确保执行块时不会释放self。如果该块本身进行异步操作,这为发生该事件提供了一个窗口,则这很重要。
在第一种情况下,该块捕获变量self
,它是强引用(即其类型为test01ViewController * __strong
)。
在第二种情况下,该块捕获变量weakSelf
,它是一个弱引用(即其类型为test03ViewController * __weak
)。