iOS中Block循环引用及解决方案(记录备用)

Block循环引用以及解决方案

此贴推荐重点阅读↓

参考贴:深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用
此贴推荐重点阅读↑

iOS开发——Block引起循环引用的解决方案

循环引用,看我就对了

Block循环引用的三种解决方式

iOS中block的循环引用问题

ARC下用块(block)的循环引用问题样例探究

造成循环引用的原因(套用别人的成果)

======
//情况一  : 不会循环引用, 不会内存泄露
- (void)case1 {
    NSLog(@"case 1 Click");
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.name = @"case 1";
    });
}
======
//情况二 : 不会循环引用,不会内存泄露
- (void)case2 {
    NSLog(@"case 2 Click");
    __weak typeof(self) weakSelf = self;
    [self.teacher requestData:^(NSData *data) {
        typeof(weakSelf) strongSelf = weakSelf;
       strongSelf.name = @"case 2";
    }];
}
======
//情况三 : 典型的循环引用
- (void)case3 {
    NSLog(@"case 3 Click");
    [self.teacher requestData:^(NSData *data) {
        self.name = @"case 3";
    }];
}
======
//情况四 : 不会循环引用,self不再强引用teacher,但若block不执行,依然会循环引用
- (void)case4 {
    NSLog(@"case 4 Click");
    [self.teacher requestData:^(NSData *data) {
        self.name = @"case 4";
        self.teacher = nil;
    }];
}
======
//情况五 : 不会循环引用,self未强引用 Teacher的实例对象
- (void)case5 { 
    NSLog(@"case 5 Click");
    Teacher *t = [[Teacher alloc] init];
    [t requestData:^(NSData *data) {
        self.name = @"case 5";
    }];
}
======
//情况六 不会循环引用,self.teacher不再强引用case6Block,但若block不执行,依然会循环引用
- (void)case6 {
    NSLog(@"case 6 Click");
    [self.teacher callCase6BlackEvent];
    self.teacher.case6Block = ^(NSData *data) {
        self.name = @"case 6";
    self.teacher.case6Block = nil;
    };
}

解决方法 1

    NSLog(@"case 2 Click");
    __weak typeof(self) weakSelf = self;
    [self.teacher requestData:^(NSData *data) {
        typeof(weakSelf) strongSelf = weakSelf;
       strongSelf.name = @"case 2";
    }];

解决方法 2

使用 @weakify , @strongify 这两个宏定义

@weakify, @strongify

@weakify(self); // 定义了一个__weak的self_weak_变量 
[RACObserve(self, name) subscribeNext:^(NSString *name) { 
    @strongify(self); // 局域定义了一个__strong的self指针指向self_weak 
    self.outputLabel.text = name; 
}];

补充内容(1)

这样也会造成循环引用

    ABCBlock *abc = [[ABCBlock alloc] init];
    abc.block = ^{
        self.ssss = @"";
    };

    self.aaaa = [NSMutableArray arrayWithCapacity:0];
    [self.aaaa addObject:abc];

}

- (void)dealloc{
    NSLog(@"-------- dealloc ---------");
}

以上这个和 情况五 相似.
iOS中Block循环引用及解决方案(记录备用)_第1张图片
虽然 ABCBlock的实例并不是当前类的成员属性,但其实该类(self)的其他成员属性却依旧持有abc (将其添加进数组中), 所以以上这种情况,也是不会执行dealloc()方法的.需要注意.
iOS中Block循环引用及解决方案(记录备用)_第2张图片

补充内容(2)

@weakify | @strongify

    @weakify(<#object#>);
    @strongify(<#object#>)
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif


#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif

结合XCODE代码块快捷功能

iOS中Block循环引用及解决方案(记录备用)_第3张图片

iOS中Block循环引用及解决方案(记录备用)_第4张图片

待补充待完善.

你可能感兴趣的:(#,iOS,报错集合,#,iOS,优化,#,iOS,Block,#,iOS,语法技巧)