1. 程式人生 > >iOS開發——Block使用小結

iOS開發——Block使用小結

就會 pri nbsp inter 產生 方式 return語句 bject 自動

  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使用小結