- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. Person *xiaozhang = [Person new]; xiaozhang.FeedAnimalBlock = ^(BOOL hasFeed) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [xiaozhang feedOver]; }); }; }
xiaozhang引用feedBlock,block中引用xiaozhang,常见的循环引用。
初级解决方案:在block外部,声明一个弱指针引用xiaozhang,若指针不会增加引用计数,打破了引用循环
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. Person *xiaozhang = [Person new]; __weak typeof(xiaozhang)weakXiaozhang = xiaozhang; xiaozhang.FeedAnimalBlock = ^(BOOL hasFeed) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [weakXiaozhang feedOver]; }); }; }
循环引用的问题解决了,但是发现feedOver的方法并没有被调用
分析:feedOver方法在2s之后执行,以为着viewDidLoad早已经执行完毕,而xiaozhang作为内部成员变量已经被释放,弱指针weakXiaozhang同时也被释放掉了,当然feedOver就不会调用
思路:ViewDidLoad执行完毕之后,block外部xiaozhang被释放,要执行feedOver的方法,就要求在block中有一个指向xiaozhang的强指针,这样就不会被释放了,外部创建强引用的话又会出现循环引用
解决方案:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. Person *xiaozhang = [Person new]; __weak typeof(xiaozhang)weakXiaozhang = xiaozhang; xiaozhang.FeedAnimalBlock = ^(BOOL hasFeed) { __strong typeof(weakXiaozhang)strongXiaozhang = weakXiaozhang; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [strongXiaozhang feedOver]; }); }; }
在block内部强引用person对象,生命周期和block的生命周期相同,当2s之后feedOver执行完,block生命周期结束,延时器和stronXiaozhang都会被销毁。