- (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都会被销毁。