ios block常見的錯誤(二)——循環引用

這篇博文繼續block的常見錯誤——循環引用。程序員

循環引用是不少初學者不能察覺的,其產生的緣由,是block中的代碼會對對象進行強引用數組

讀者請閱讀示例代碼1,並思考示例代碼1所建立的對象可否被正常銷燬?xcode

示例代碼1:atom

複製代碼

* mark 將代碼改成調用self的方法

-(NSMutableArray * (_myBlocks ===-=(^sum)(, ) = ^( x,  mark 對象被釋放時自動調用
- (

複製代碼

結果是不能正常釋放的。讀者不妨在xcode中試試。spa

產生緣由在block代碼中出現了self:code

int(^sum)(int, int) = ^(int x, int y) {    return [self sum:x y:y];
};

此時sum的block對self強引用,在加上self對myBlocks強引用:orm

@property (nonatomic, strong) NSMutableArray *myBlocks;

以及sum block被添加到數組時,會被數組強引用:對象

[self.myBlocks addObject:sum];

這三個引用之間造成了循環引用,以下圖:it

循環引用的結果就是對象沒法被釋放!table

碰到這類問題,程序員如何解除循環引用呢?

有如下幾種解決方案:

1.在block代碼中不要引用self以及其餘局部變量;如

int(^sum)(int, int) = ^(int x, int y) {    return [self sum:x y:y];
};

修改爲

int(^sum)(int, int) = ^(int x, int y) {    return x + y;
};

 

2.使用__weak關鍵字,能夠將局部變量聲明爲弱引用

如:

複製代碼

- (instancetype)init
{
    self = [super init];    if (self) {        int(^sum)(int, int) = ^(int x, int y) {            return [self sum:x y:y];
        };
        [self.myBlocks addObject:sum];
    }    
    return self;
}

複製代碼

修改成:

複製代碼

- (instancetype)init
{
    self = [super init];    if (self) {
        __weak DemoObj *weakSelf = self;        int(^sum)(int, int) = ^(int x, int y) {            return [weakSelf sum:x y:y];
        };
        [self.myBlocks addObject:sum];
    }    
    return self;
}

複製代碼

block的循環引用就說到這,下一篇繼續來說解block的常見錯誤

相關文章
相關標籤/搜索