关于IOS,多线程Block中的self循环引用问题!

来源:互联网 发布:手机淘宝3.9 编辑:程序博客网 时间:2024/05/17 04:45
如果self对象持有操作对象的引用,同时操作对象当中又直接访问了self时,才会造成循环引用

单纯在操作对象中使用self不会造成循环引用
#import "DemoObj.h"@interface DemoObj()@property (nonatomic, strong) NSOperationQueue *queue;@end@implementation DemoObj- (instancetype)init{    self = [super init];    if (self) {        self.queue = [[NSOperationQueue alloc] init];    }        return self;}- (void)dealloc{    NSLog(@"demoobj dealloc");}- (void)demoOp:(id)obj{    NSLog(@"%@ %@", [NSThread currentThread], obj);}- (void)demoBlockOp{    // 不能用__weak//    __weak DemoObj *weakSelf = self;    // 只有self直接强引用block,才会出现循环引用    // block的管理以及线程的创建和销毁是由队列负责的,直接在block中使用self没有关系!    for (int i = 0; i < 10; ++i) {                <span style="color:#ff6666;">[self.queue addOperationWithBlock:^{            [self demoOp:@(i)];        }];</span>    }}@end

代码如上:

如果使用[weakSelf demoOp:@(i)];这段代码
因为block中的代码是在程序后台执行,当前代码执行完后,如果在self被其他代码中被释放后,当前的10个线程还没有全部执行完,这是再去执行block中的代码,发现self为nil,执行[nil demoOp:@(i)]; 程序不会执行该方法

反之,如果使用[self demoOp:@(i)];  即使其他地方定义的self被释放后,self并没有执行dealloc方法,因为因为block对self进行了强引用,self并没有被真正释放,所以可以继续执行[self demoOp:@(i)]方法,当该队列所有线程执行玩后,队列删除,self也随之删除,并不会造成内存泄露。并且所有的线程也能正常执行。
0 0
原创粉丝点击