標籤:返回 執行 通過 就會 void 錯誤 imp 編譯 說明
Block文法看上去好像很特別,但它實際上是作為極普通的C語言原始碼處理的。Block的實質,就是Objective-C的對象。
1、Block的文法
^ 傳回值類型 參數列表 運算式
可省略傳回值類型:^ 參數列表 運算式。省略傳回值類型時,如果運算式中有return語句就使用該傳回值的類型,如果運算式中沒有return語句,就使用void類型。
再省略參數列表:^ 運算式。這個就是大家最熟知的記敘方式。
int val = 10;
void (^blk)(void) = ^{
printf("val = %d\n",val);
};
blk();
2、__block說明符
若想在Block文法的運算式中將值賦給在Block文法外聲明的自動變數,需要在該自動變數上附加__block說明符。不然就會產生編譯錯誤。
__block int val = 10;
void (^blk)(void) = ^{
val = 11;
};
blk();
printf("val = %d\n",val);
3、Block循環參考
先看看下面的原始碼吧!
typedef void(^blk_t)(void);
@interface MyObject : NSObject{
blk_t blk_;
}
@end
@implementation MyObject
- (id)init {
self = [super init];
blk_ = ^{
NSLog(@"self = %@",self);
};
return self;
}
@end
MyObject類對象的Block類型成員變數blk_持有賦值為Block的強引用。即MyObject類對象持有Block。init執行個體方法中執行的Block文法使用持有__strong修飾符的id類型變數self。並且由於Block文法賦值在了成員變數blk_中,因此通過Block文法產生在棧上的Block此時由棧複製到堆,並持有所使用的self。self持有Block,Block持有self。這正是循環參考。
為避免循環參考,可聲明附有__weak修飾符的變數,並將self賦值使用。
- (id)init {
self = [super init];
id __weak tmp = self;
blk_ = ^{
NSLog(@"self = %@",tmp);
};
return self;
}
iOS開發——Block使用小結