1、三種類型的block介紹
根據Block在內存中的位置分為三種類型NSGlobalBlock,NSStackBlock, NSMallocBlock。
NSGlobalBlock:類似函數,位于代碼段;
NSStackBlock:位于棧內存,函數返回后Block將無效;
NSMallocBlock:位于堆內存
1)全局block(__NSGlobalBlock__),定義在函數外面的block是global的;另外如果函數內部的
block,但是沒有捕獲任何自動變量,那么它也是全局的(ARC和MRC都一樣)。
2)棧block,
在MRC下,棧block
在MRC下,使用外部變量的b1是棧block,在其內部對棧外部變量復制,并且放到了棧區。
3)堆block則是對棧blockcopy得來。對全局block copy 不會有任何作用,返回的依然是全局block。
總結:
1)ARC下
-沒有使用外部變量Global
分區 第三天(@傳智如意大師) 的第16頁
-沒有使用外部變量
-使用外部變量
2)MRC下
-沒有使用外部變量
-使用外部變量
3)對一個棧block通過copy可以得到堆block
2、block類型變量內存管理參數為什么要使用copy?
1)如果不使用copy,使用assign帶來的問題
@property(nonatomic,assign)void(^myblock)();
定義一個Person類來演示問題
@interfacePerson : NSObject
@property(nonatomic,assign)void(^myblock)();
-(void)test;
@end
@implementationPerson
-(void)test{
int n =5;
void(^bb)()= ^{
NSLog(@"myblock! n = %d",n);
};
self.myblock= bb;
NSLog(@"self stackBlock --->%@",self.myblock);
NSLog(@"self stackBlock --->%@",self.myblock);
}
@end
在ARC下測試:self.myblock應該為堆區,而實際打印出來卻為棧區.
在MRC下測試:在MRC下,使用了外部變量n,blook在棧區.
由此可知,不管再MRC還是在ARC,使用assign修飾的block,都是棧block.
如果使用copy后,則 棧block -----copy-------得到的是堆block,不會出現問題。