1. block的底層實(shí)現(xiàn)原理
- block實(shí)際上是指向結(jié)構(gòu)體的指針;block傳值時(shí):普通的局部變量是值傳遞,全局變量、被static修飾的局部變量或者被__block修飾的局部變量都是地址傳遞
//普通的局部變量-->值傳遞
void test1()
{
int a = 10;
void(^block)() = ^{
NSLog(@"a is %d",a);
};
a = 20;
block();
}
此時(shí)打印出來的東西是a is 10(值傳遞)。
//全局變量-->地址傳遞
int a = 10;
void test2()
{
void(^block)() = ^{
NSLog(@"a is %d",a);
};
a = 20;
block();
}
此時(shí)打印出來的東西是a is 20(地址傳遞)。
//被__block修飾的局部變量-->地址傳遞
void test3()
{
__block a = 10;
void(^block)() = ^{
NSLog(@"a is %d",a);
};
a = 20;
block();
}
此時(shí)打印出來的東西是a is 20(地址傳遞)。
//被static修飾的局部變量-->地址傳遞
void test4()
{
static a = 10;
void(^block)() = ^{
NSLog(@"a is %d",a);
};
a = 20;
block();
}
此時(shí)打印出來的東西是a is 20(地址傳遞)。
- 在查看block底層實(shí)現(xiàn)原理的過程中,需要把系統(tǒng)的OC代碼轉(zhuǎn)換成c++代碼,具體的轉(zhuǎn)化需要在終端找到文件路徑并執(zhí)行以下代碼:
clang - rewrite-objc ***(文件名)
2. block的內(nèi)存管理
- 默認(rèn)情況下block的內(nèi)存是在棧中(不需要手動(dòng)去管理block內(nèi)存),它不會(huì)對(duì)所引用的對(duì)象進(jìn)行任何操作
- 如果對(duì)block進(jìn)行了copy操作, block的內(nèi)存會(huì)搬到堆里面,它會(huì)對(duì)所引用的對(duì)象做一次retain操作
注意:
非ARC: 如果所引用的對(duì)象用了__block修飾,就不會(huì)做retain操作。
ARC: 如果所引用的對(duì)象用了__unsafe_unretained\__weak修飾,就不會(huì)做retain操作。
為什么加上 __block就可以修改外部的變量了?
真正的原因是這樣的:
我們都知道:Block不允許修改外部變量的值,這里所說的外部變量的值,指的是棧中指針的內(nèi)存地址。__block
所起到的作用就是只要觀察到該變量被 block 所持有,就將“外部變量”在棧中的內(nèi)存地址放到了堆中。進(jìn)而在block內(nèi)部也可以修改外部變量的值。
站在巨人的肩膀上,本文借鑒@M了個(gè)J小馬哥教程.謝謝??