(ps.本文提到有typedef和typeof)
block是帶有自動變量的匿名函數(shù).
- 匿名函數(shù)
匿名函數(shù)顧名思義就是不帶名字的函數(shù)名扛,在C語言中不允許這樣的方法存在誓篱,而在OC中的Block則可以用指針來直接調(diào)用一個函數(shù)仍劈。 - 自動變量
block可以截獲變量的瞬時值....截獲的變量可以進行操作而不能進行賦值.
block中不能再改變變量的值.....如果需要改變變量的值需要在變量聲明時加上__Block修飾符.
block不支持C語言數(shù)組.
block語法
一個完整的block
^ NSString *(NSString *a,NSString *b){
return a;
};
"^" block標識......."NSString *"返回值...."(NSString *a,NSString *b)"參數(shù)列表..
其實我們可以直接省略返回值....沒有參數(shù)的時候也可以省略返回值.
^ {
NSLog(@"hello world");
};
block變量
其實就是一個指向block的指針.
int (^blockName)(int arg1,int arg2);
我們可以通過等號賦值直接給block變量賦值,
int (^blockName)(int arg1,int arg2) = ^(int arg1, int arg2){
return arg1 + arg2;
};
block當作函數(shù)參數(shù)
我們可以先聲明一個block變量.并加上typedef標識符
(typedef表示為已知的類型起別名,在這里表示為block取一個叫MyBlock的別名,這樣我們再定義這個block類型是就可以直接用Myblock,而不必加上其他額外的東西)
typedef void (^MyBlock)(NSString *s1,UIColor *c);
我們來聲明一個函數(shù):
-(void)func:(MyBlock)block{
block(@"str",[UIColor redColor]);
}
我們可以使用這個函數(shù):
[self func:^(NSString *s1, UIColor *c){
NSLog(@"%@",s1);
self.view.backgroundColor = c;
}];
循環(huán)引用問題
block在ios開發(fā)中被視為一個對象....由于block的捕獲變量的機制...使得block的對象也有可能被block持有,從而形成循環(huán)應用,導致兩者都不能被釋放...
如下,
@implementation LXDObject
{
void (^_cycleReferenceBlock)(void);
}
- (void)viewDidLoad
{
[super viewDidLoad];
_cycleReferenceBlock = ^{
NSLog(@"%@", self); //引發(fā)循環(huán)引用
};
}
@end
我們可以通過__weak關(guān)鍵字來修飾變量,解決循環(huán)引用問題
__weak typeof(*&self) weakSelf = self;
_cycleReferenceBlock = ^{
NSLog(@"%@", weakSelf); //弱指針引用,不會造成循環(huán)引用
};
(typeof可以根據(jù)括號內(nèi)的變量,自動識別變量類型并返回該類型)