^{ NSLog(@"This is a block"); }
void (^simpleBlock)(void);
相似int i;html
simpleBlock = ^{ NSLog(@"This is a block"); }
相似i = 2;ide
void (^simpleBlock)(void) = ^{ NSLog(@"This is a block"); }
相似int i = 2;函數
simpleBlock();
^(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);
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.atom
Block定義的時候,將值複製一份給本身,因此該值已經不受外界影響。spa
__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裏面的值與外面的值共享同一分內存code
It’s important to take care when capturing self because it’s easy to create a strong reference cycle when capturing self.htm
由於變量默認是__strong修飾(詳見這裏),因此要時刻注意在block裏面對self的引用(只要出現了self關鍵字就算引用了,由於block會自動capture)blog
假如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();
圖解
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 int (^Sum)(int, int); Sum mySum = ^(int a, int b){ return a+b; }
or
typedef void (^XYZSimpleBlock)(void); @property (copy) XYZSimpleBlock blockProperty;
@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.