RunTime 參考:http://www.reibang.com/p/6ebda3cd8052
RunLoop 參考:http://www.reibang.com/p/de752066d0ad
什么是Block献汗,Block的本質(zhì)是什么式曲?
block本質(zhì)上也是一個(gè)OC對(duì)象务漩,它內(nèi)部也有個(gè)isa指針
block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對(duì)象
block是封裝函數(shù)及其上下文的OC對(duì)象
int age=10;
void (^Block)(void) = ^{
? ? NSLog(@"age:%d",age);
};
age = 20;
Block();
輸出值為 age:10
原因:創(chuàng)建block的時(shí)候它匕,已經(jīng)把a(bǔ)ge的值存儲(chǔ)在里面了于毙。
auto int age = 10;
static int num = 25;
void (^Block)(void) = ^{
? ? NSLog(@"age:%d,num:%d",age,num);
};
age = 20;
num = 11;
Block();
輸出結(jié)果為:age:10,num:11
愿意:auto變量block訪問(wèn)方式是值傳遞,static變量block訪問(wèn)方式是指針傳遞
為什么block對(duì)auto和static變量捕獲有差異?
auto自動(dòng)變量可能會(huì)銷(xiāo)毀的,內(nèi)存可能會(huì)消失础爬,不采用指針訪問(wèn);static變量一直保存在內(nèi)存中吼鳞,指針訪問(wèn)即可
為什么block對(duì)auto和static變量捕獲有差異看蚜?
auto自動(dòng)變量可能會(huì)銷(xiāo)毀的,內(nèi)存可能會(huì)消失赔桌,不采用指針訪問(wèn)供炎;static變量一直保存在內(nèi)存中,指針訪問(wèn)即可
block對(duì)全局變量的捕獲方式是疾党?
block不需要對(duì)全局變量捕獲音诫,都是直接采用取值的
block的類(lèi)型,取決于isa指針雪位,可以通過(guò)調(diào)用class方法或者isa指針查看具體類(lèi)型竭钝,最終都是繼承自NSBlock類(lèi)型
__NSGlobalBlock __ ( _NSConcreteGlobalBlock )
__NSStackBlock __ ( _NSConcreteStackBlock )
__NSMallocBlock __ ( _NSConcreteMallocBlock )
各類(lèi)型的block在內(nèi)存中如何分配的?
__NSGlobalBlock __ 在數(shù)據(jù)區(qū)
__NSMallocBlock __ 在堆區(qū)
__NSStackBlock __ 在棧區(qū)
堆:動(dòng)態(tài)分配內(nèi)存雹洗,需要程序員自己申請(qǐng)蜓氨,程序員自己管理
棧:自動(dòng)分配內(nèi)存,自動(dòng)銷(xiāo)毀队伟,先入后出,棧上的內(nèi)容存在自動(dòng)銷(xiāo)毀的情況
如何判斷block是哪種類(lèi)型幽勒?
沒(méi)有訪問(wèn)auto變量的block是__NSGlobalBlock __ 嗜侮,放在數(shù)據(jù)段
訪問(wèn)了auto變量的block是__NSStackBlock __
[__NSStackBlock __ copy]操作就變成了__NSMallocBlock __
對(duì)每種類(lèi)型block調(diào)用copy操作后是什么結(jié)果?
__NSGlobalBlock __ 調(diào)用copy操作后啥容,什么也不做
__NSStackBlock __ 調(diào)用copy操作后锈颗,復(fù)制效果是:從棧復(fù)制到堆;副本存儲(chǔ)位置是堆
__NSStackBlock __ 調(diào)用copy操作后咪惠,復(fù)制效果是:引用計(jì)數(shù)增加击吱;副本存儲(chǔ)位置是堆
在ARC環(huán)境下,編譯器會(huì)根據(jù)情況自動(dòng)將棧上的block復(fù)制到堆上的幾種情況遥昧?
1.block作為函數(shù)返回值時(shí)
2.將block賦值給__strong指針時(shí)
3.block作為Cocoa API中方法名含有usingBlock的方法參數(shù)時(shí)
4.block作為GCD API的方法參數(shù)時(shí)
ARC下如何解決block循環(huán)引用的問(wèn)題覆醇?
三種方式:__weak朵纷、__unsafe_unretained、__block
第一種方式:__weak
Person *person = [[Person alloc] init];
//? ? ? ? __weak Person *weakPerson = person;
__weak typeof(person) weakPerson = person;
person.block = ^{
? ? NSLog(@"age is %d", weakPerson.age);
};
第二種方式:__unsafe_unretained
__unsafe_unretained Person *person = [[Person alloc] init];
person.block = ^{
? ? NSLog(@"age is %d", weakPerson.age);
};
第三種方式:__block
__block Person *person = [[Person alloc] init];
person.block = ^{
? ? NSLog(@"age is %d", person.age);
? ? person = nil;
};
person.block();
2.?程序crash的原因?
1.賦值?setObjectForKey key不能為nil,object不能為nil?[dic objectForKey:key]; key可以為nil
2.?控件屬性重復(fù)拉線永脓,一個(gè)控件拉出兩個(gè)屬性
3.?調(diào)用block需要判斷是否為空
4.?使用NSTimer 的target被釋放了袍辞,而timer還去執(zhí)行定時(shí)方法,回調(diào)的時(shí)候找不到對(duì)象就會(huì)掛掉
5.?給datePicker賦值的NSDate為nil常摧,可能因?yàn)槿掌诟袷交址粚?duì)
6.?kvo沒(méi)有移除監(jiān)聽(tīng)搅吁,或者kvo多次注冊(cè)監(jiān)聽(tīng)
7. Range or index out of bounds
8.? unrecognized selector sent to instance
9.?數(shù)組范圍越界