1.__block簡介
__block可以用于解決block內(nèi)部無法修改auto變量值的問題喂饥, __block不能修飾全局變量碍讨、靜態(tài)變量(static)捉超,編譯器會將__block變量(不管是基本數(shù)據(jù)類型還是對象類型)包裝成一個(gè)對象泳梆。
- 代碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "YMPerson.h"
typedef void(^YMBlock)(void);
int main(int argc, char * argv[]) {
@autoreleasepool {
// 基本數(shù)據(jù)類型
__block int a = 10;
YMBlock block = ^{
a = 20;
};
block();
NSLog(@"a == %d",a);
// 對象類型
YMPerson *person = [[YMPerson alloc] init];
person.age = 10;
__block YMPerson *blockPerson = person;
YMBlock block1 = ^{
// 這不是修改person對象 是使用person對象 此步驟不使用__block修飾也可
person.age = 20;
// 修改person對象勿侯,必須用__block修飾
blockPerson = [[YMPerson alloc] init];
blockPerson.age = 100;
};
block1();
NSLog(@"person.age == %d",person.age);
NSLog(@"blockPerson.age == %d",blockPerson.age);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
-
運(yùn)行結(jié)果
block修飾
2.__block修飾變量的內(nèi)存管理
1.當(dāng)block在棧上時(shí)蛉腌,并不會對__block變量產(chǎn)生強(qiáng)引用官份。
2.當(dāng)__block變量被copy到堆時(shí)只厘,會調(diào)用__block變量內(nèi)部的copy函數(shù),copy函數(shù)內(nèi)部會調(diào)用_Block_object_assign函數(shù)舅巷,_Block_object_assign函數(shù)會根據(jù)所指向?qū)ο蟮男揎棧╛_strong羔味、__weak、__unsafe_unretained)做出相應(yīng)的操作钠右,形成強(qiáng)引用(retain)或者弱引用(注意:這里僅限于ARC時(shí)會retain赋元,MRC時(shí)不會retain)。
3. 如果__block變量從堆上移除飒房,會調(diào)用__block變量內(nèi)部的dispose函數(shù)搁凸,dispose函數(shù)內(nèi)部會調(diào)用_Block_object_dispose函數(shù),_Block_object_dispose函數(shù)會自動釋放指向的對象(release)狠毯。
3.__block __weak同時(shí)修飾
block內(nèi)部不會對對象進(jìn)行強(qiáng)引用
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "YMPerson.h"
typedef void(^YMBlock)(void);
int main(int argc, char * argv[]) {
@autoreleasepool {
YMBlock block;
{
YMPerson *person = [[YMPerson alloc] init];
person.age = 10;
__block __weak YMPerson *blockPerson = person;
block = ^{
blockPerson.age = 100;
};
}
block();
NSLog(@"---");
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
-
運(yùn)行結(jié)果
__block __weak 同時(shí)修飾