iOS 使用block屬性問題

1.block屬性的聲明

block屬性的聲明,需要copy修飾符,因為只有copy后的block才會在堆中,棧中的block的生命周期是和棧綁定的

2.block線程安全

在聲明block屬性時需要確認“在調用block時另一個線程有沒有可能去修改block?”確定不會有,block聲明可以用nonatomic。不確定(通常是不確定),需要 聲明block屬性為atomic,先保證變量的原子性。

比如這樣一個block類型

typedef ? void ?(^MyBlockType)(int);

屬性聲明:@property(copy) ?MyBlockType ? myBlock;

但是,有atomic來保證基本的原子屬性還是沒有達到線程安全,接著在調用時需要把block先賦值給本地變量,以防止block突然改變。因為如果不這樣的話,即便先判斷了block屬性不為空,在調用之前,一旦另一個線程把block屬性設空了,程序就會crash

正確的代碼是(ARC):

MyBlockType ? ?block = self.myBlock;//block現在是本地不可變

if(block){

block(123);

}

非ARC下需要手動retain一下,否則屬性被置空,本地變量就成了野指針

MyBlockType ?block = [self.myBlock ? retain];

if(block){

block(123);

}

[block release];

3.循環引用

ARC下,由于__block抓取的變量一樣會被block retain,所以必須用弱引用才可以解決循環引用問題,iOS5之后用__weak。

__weak ? ? typeof(self) ? ? ?weakSelf = self;

self.myBlock = ^(int ? paramInt) ? {

[weakSelf ?anotherFunc];

};

非ARC,無法使用弱引用,用__block來修飾變量,它不會被block所retain的

__block ?typedef(self) ? ?blockSelf = self;

self.myBlock = ^(int? paramInt)? {

[blockSelf ? anotherFunc];

};

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容