標籤:
Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary.
Block文法——無參數版本定義(Block的值)
^{ NSLog(@"This is a block");}
聲明
void (^simpleBlock)(void);
類似int i;
賦值
simpleBlock = ^{ NSLog(@"This is a block"); }
類似i = 2;
聲明的時候定義
void (^simpleBlock)(void) = ^{ NSLog(@"This is a block");}
類似int i = 2;
調用
simpleBlock();
Block文法——帶參數版本定義
^(double firstValue, double secondValue){ return firstValue * secondValue;}
or
^double (double firstValue, double secondValue) { return firstValue * secondValue;}
聲明
double (^multiplyTwoValues)(double, double);
賦值
multiplyTwoValues = ^(double firstValue, double secondValue) { return firstValue * secondValue;};
聲明的時候定義
double (^multiplyTwoValues)(double, double) =^(double firstValue, double secondValue) { return firstValue * secondValue;};
調用
double result = multiplyTwoValues(2,3);
__block修飾符
int anInteger = 42;void (^testBlock)(void) = ^{ //此時只是Block定義,並沒有執行裡面的函數 NSLog(@"Integer is: %i", anInteger);};anInteger = 84;testBlock(); //Block調用 輸出42
Value is captured when the block is defined.
Block定義的時候,將值複製一份給自己,所以該值已經不受外界影響。
__block int anInteger = 42;void (^testBlock)(void) = ^{ //此時只是Block定義,並沒有執行裡面的函數 NSLog(@"Integer is: %i", anInteger); };anInteger = 84;testBlock(); //Block調用 輸出84
Because anInteger is declared as a __block variable, its storage is shared with the block declaration.
此時Block裡面的值與外面的值共用同一份記憶體
Block與self的恩怨情仇
It’s important to take care when capturing self because it’s easy to create a strong reference cycle when capturing self.
因為變數預設是__strong修飾(詳見這裡),所以要時刻注意在block裡面對self的引用(只要出現了self關鍵字就算引用了,因為block會自動capture)
假如self裡面定義了一個block,那麼self有一個指向block的strong指標(比如該block是self的一個strong成員變數);假如block裡面使用了self,則block也預設拷貝了一個指向self的strong指標,此時形成strong reference cycle.
解決方案:在Block前面建立一個__weak類型的指向self的指標,並在block裡面使用該指標。
例子
__weak typeof(self) weakSelf = self; //學習下這種寫法哦 typeof(self)self.simpleBlock = ^{ [weakSelf f];};...self.simpleBlock();
但是,假如Block裡面又有一個Block,怎麼辦?最好是強引用weakSelf,此時strongSelf強引用的是weakSelf而不是self,所以不會形成strong reference cycle
__weak typeof(self) weakSelf = self; //學習下這種寫法哦 typeof(self)self.simpleBlock = ^{ [weakSelf f]; __strong typeof(weakSelf) strongSelf = weakSelf; self.simpleBlock2 = ^{ [strongSelf f]; }; self.simpleBlock2();};...self.simpleBlock();
圖解
一個函數最好只有一個Block參數,且最好是在最後一個
A Block Should Always Be the Last Argument to a Method.
It’s best practice to use only one block argument to a method.
使用typedef定義一個block
typedef int (^Sum)(int, int);Sum mySum = ^(int a, int b){ return a+b;}
or
typedef void (^XYZSimpleBlock)(void);@property (copy) XYZSimpleBlock blockProperty;
使用copy修飾block的property
@property (nonatomic, copy) Sum mySum;@property (nonatomic, copy) void (^blockProperty)(void);
非ARC下就必須寫copy,because a block needs to be copied to keep track of its captured state outside of the original scope
在ARC下寫不寫copy都無所謂,so it‘s a best practice to set copy property for block whether it‘s ARC or not.
《Programming with Objective-C》第八章 Working with Blocks