block實際上就是Objective-C語言對閉包的實現。
- NSString * ( ^ myBlock )( int );
上面的代碼聲明了一個block(^)原型,名字叫做myBlock,包含一個int型的參數,返回值為NSString類型的指針。
下面來看看block的定義:
myBlock = ^( int paramA )
{
return [ NSString stringWithFormat: @"Passed number: %i", paramA ];
};
上面的代碼中,將一個函數體賦值給了myBlock變量,其接收一個名為paramA的參數,返回一個NSString對象。
注意:一定不要忘記block后面的分號。
定義好block后,就可以像使用標準函數一樣使用它了:
myBlock(7);
2 block 的使用 : 如果block是一個屬性,在調用block的時候,如果block函數體中 調用了 [self did]就出出現循環引用,因為A中有B B中有A 互相調用,就會出現問題,如果block不是屬性,則不會出現循環引用,例如:
[UIView animateWithDuration: 0.5 animations: ^{
self.userName.center = accountCenter;
self.password.center = passwordCenter;
self.login.alpha = 1;
} completion: nil];這個為啥會可以使用self,因為這個view不是這個控制器的屬性,所以不會又循環引用的問題
如果需要解決循環引用的問題可以
//先聲明一個weak弱對象
__weak ViewController *wSelf = self;
[UIView animateWithDuration: 0.5 animations: ^{
//在block的執行過程中,使用強對象對弱對象進行引用
wSelf.userName.center = accountCenter;
wSelf.password.center = passwordCenter;
wSelf.login.alpha = 1;
}
3//聲明一個局部整型變量
int intValue = 3;
//聲明一個返回值為int,一個int參數的block變量
int (^block)(int) = ^(int m){
intValue++;
return m * intValue;
};
//調用block變量,5作為參數之后的結果
NSLog(@"block(5) = %d",block(5));
在上面的例子中,我們編譯程序后發現編譯器會有紅色錯誤,錯誤提示為
Variable is not assignable (missing __block type specifier)
為什么會出現不能被賦值的錯誤提示呢?
block在實現時就會對它引用到的它所在方法中定義的棧變量進行一次只讀拷貝,所以intValue只是可讀的,不能操作
在 block 塊內使用該只讀拷貝。
那為了避免上述錯誤,就要使用__block修飾符來修飾外部變量,用來通知編譯器該外部變量intValue與block中的intValue指的是同一塊兒內存地址,而不需要內存拷貝。
所以 __block int intValue = 3;這樣才行如果 是 intValue;也會正常運行,