1、修飾屬性有哪幾個(gè)情萤?追問(wèn) 為什么用copy鸭蛙?weak對(duì)象為nil的底層原理?
2筋岛、block是什么娶视?block有幾種?追問(wèn) 為什么__block修飾的值在內(nèi)部可以改變
3睁宰、字典大致實(shí)現(xiàn)原理
4肪获、一般開(kāi)始做一個(gè)項(xiàng)目,你的架構(gòu)是如何思考的勋陪?
5、runLoop機(jī)制硫兰?source0是什么诅愚?source1是什么?追問(wèn) 事件響應(yīng)時(shí)怎么通知runLoop的劫映?
6违孝、runtime是什么?superclass是什么類(lèi)型的泳赋?math_list里有什么雌桑?追問(wèn)SEL里面有什么(知道的請(qǐng)告訴我,查資料沒(méi)找到)祖今?
7校坑、objc_class結(jié)構(gòu)體
一拣技、類(lèi)在OC中是objc_class的結(jié)構(gòu)體指針 typedef struct objc_class *Class;
在objc/runtime.h中objc_class結(jié)構(gòu)體的定義如下:
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父類(lèi)
const char *name OBJC2_UNAVAILABLE; // 類(lèi)名
long version OBJC2_UNAVAILABLE; // 類(lèi)的版本信息,默認(rèn)為0
long info OBJC2_UNAVAILABLE; // 類(lèi)信息耍目,供運(yùn)行期使用的一些位標(biāo)識(shí)
long instance_size OBJC2_UNAVAILABLE; // 該類(lèi)的實(shí)例變量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 該類(lèi)的成員變量鏈表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定義的鏈表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法緩存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 協(xié)議鏈表
#endif
} OBJC2_UNAVAILABLE;
isa: 指向元類(lèi)的objc_class結(jié)構(gòu)體指針膏斤,iOS中的類(lèi)也是對(duì)象,元類(lèi)中儲(chǔ)存有類(lèi)對(duì)象的類(lèi)方法邪驮;
superclass: 指向父類(lèi)的objc_class結(jié)構(gòu)體指針莫辨,可以通過(guò)父類(lèi)的指針找到變量和方法萎羔;
name: 類(lèi)名赡茸;
version: 版本號(hào)更振,默認(rèn)為0
info: 其他信息康愤,運(yùn)行期間的一些位標(biāo)示
instance_size:類(lèi)實(shí)例變量大小
objc_class的定義
我們?cè)谑褂胷untime以class為前綴的方法時(shí)主要就是針對(duì)這個(gè)結(jié)構(gòu)體中的各個(gè)字段的顶燕。
指向元類(lèi)的指針(isa)
在OC中所有的類(lèi)其實(shí)也是一個(gè)對(duì)象贮匕,那么這個(gè)對(duì)象也會(huì)有一個(gè)所屬的類(lèi)笼裳,這個(gè)類(lèi)就是元類(lèi)也就是結(jié)構(gòu)體里面isa指針?biāo)傅念?lèi)糕珊。
7磷斧、那什么是元類(lèi)呢?
元類(lèi)的定義:元類(lèi)就是類(lèi)對(duì)象的類(lèi)弛饭。每個(gè)類(lèi)都有自己的元類(lèi),因?yàn)槊總€(gè)類(lèi)都有自己獨(dú)一無(wú)二的方法档桃。
簡(jiǎn)單點(diǎn)說(shuō)就是:
當(dāng)你給對(duì)象發(fā)送消息時(shí)憔晒,消息是在尋找這個(gè)對(duì)象的類(lèi)的方法列表拒担。(實(shí)例方法)
當(dāng)你給類(lèi)發(fā)消息時(shí),消息是在尋找這個(gè)類(lèi)的元類(lèi)的方法列表州弟。(類(lèi)方法)
那元類(lèi)的類(lèi)是什么呢婆翔?
元類(lèi)掏婶,就像之前的類(lèi)一樣,它也是一個(gè)對(duì)象最蕾。你也可以調(diào)用它的方法。自然的誓沸,這就意味著他必須也有一個(gè)類(lèi)壹粟。
所有的元類(lèi)都使用根元類(lèi)(繼承體系中處于頂端的類(lèi)的元類(lèi))作為他們的類(lèi)趁仙。這就意味著所有NSObject的子類(lèi)(大多數(shù)類(lèi))的元類(lèi)都會(huì)以NSObject的元類(lèi)作為他們的類(lèi)
根據(jù)這個(gè)規(guī)則,所有的元類(lèi)使用根元類(lèi)作為他們的類(lèi)干奢,根元類(lèi)的元類(lèi)則就是它自己忿峻。也就是說(shuō)基類(lèi)的元類(lèi)的isa指針指向他自己逛尚。
這里有一副圖可以很好的展現(xiàn)這些關(guān)系:
8刁愿、category是啥铣口?category為什么不能添加屬性?有辦法解決嗎件缸?
//Category表示一個(gè)結(jié)構(gòu)體指針的類(lèi)型
typedef struct objc_category *Category;
struct objc_category {
char * _Nonnull category_name OBJC2_UNAVAILABLE;
char * _Nonnull class_name OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable instance_methods OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable class_methods OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
分類(lèi)特點(diǎn)
1.分類(lèi)是用于給原有類(lèi)添加方法的,因?yàn)榉诸?lèi)的結(jié)構(gòu)體指針中他炊,沒(méi)有屬性列表佑稠,只有方法列表旗芬。原則上講它只能添加方法, 不能添加屬性(成員變量),實(shí)際上可以通過(guò)其它方式添加屬性 ;
2.分類(lèi)中的可以寫(xiě)@property, 但不會(huì)生成setter/getter方法, 也不會(huì)生成實(shí)現(xiàn)以及私有的成員變量疮丛,會(huì)編譯通過(guò),但是引用變量會(huì)報(bào)錯(cuò);
3.如果分類(lèi)中有和原有類(lèi)同名的方法, 會(huì)優(yōu)先調(diào)用分類(lèi)中的方法, 就是說(shuō)會(huì)忽略原有類(lèi)的方法誊薄,同名方法調(diào)用的優(yōu)先級(jí)為 分類(lèi) > 本類(lèi) > 父類(lèi)呢蔫;
可以通過(guò)關(guān)聯(lián)對(duì)象給Category添加屬性
@interface NSObject (Extension)
@property (nonatomic,copy ) NSString *name;
@end
@implementation NSObject (Extension)
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name {
return objc_getAssociatedObject(self,@selector(name));
}
@end
上面是把我們看到的現(xiàn)象進(jìn)行分析片吊,思考其為什么會(huì)有這樣的現(xiàn)象呢?分類(lèi)并不會(huì)改變?cè)蓄?lèi)的內(nèi)存分布的情況全谤,它是在運(yùn)行期間決定的认然,此時(shí)內(nèi)存的分布已經(jīng)確定卷员,若此時(shí)再添加實(shí)例會(huì)改變內(nèi)存的分布情況卷胯,這對(duì)編譯性語(yǔ)言是災(zāi)難,是不允許的挺峡。
9橱赠、如果一個(gè)類(lèi)有兩個(gè)相同的分類(lèi)箫津,系統(tǒng)會(huì)調(diào)用哪個(gè)分類(lèi)的方法苏遥?
10、KVO怎么實(shí)現(xiàn)师抄,_會(huì)不會(huì)觸發(fā)教硫,成員變量會(huì)不會(huì)觸發(fā),kvc+成員變量會(huì)不會(huì)觸發(fā)茶鉴,不用setter怎么觸發(fā)kvo
答. 當(dāng)一個(gè)對(duì)象使用了KVO監(jiān)聽(tīng),iOS系統(tǒng)會(huì)修改這個(gè)對(duì)象的isa指針惭蹂,
改為指向一個(gè)全新的通過(guò)Runtime動(dòng)態(tài)創(chuàng)建的子類(lèi)剿干,子類(lèi)擁有自己的set方法實(shí)現(xiàn)穆刻,
set方法實(shí)現(xiàn)內(nèi)部會(huì)順序調(diào)用willChangeValueForKey方法氢伟、原來(lái)的setter方法實(shí)現(xiàn)朵锣、
didChangeValueForKey方法,而didChangeValueForKey方法內(nèi)部
又會(huì)調(diào)用監(jiān)聽(tīng)器的observeValueForKeyPath:ofObject:change:context:監(jiān)聽(tīng)方法飞傀。
如何手動(dòng)觸發(fā)KVO
答. 被監(jiān)聽(tīng)的屬性的值被修改時(shí)砸烦,就會(huì)自動(dòng)觸發(fā)KVO幢痘。
如果想要手動(dòng)觸發(fā)KVO颜说,則需要我們自己調(diào)用willChangeValueForKey和
didChangeValueForKey方法即可在不改變屬性值的情況下手動(dòng)觸發(fā)KVO
门粪,并且這兩個(gè)方法缺一不可玄妈。
11、iOS反射機(jī)制?
12瞭郑、iOS的timer和CADisplay的區(qū)別鸭你?
13袱巨、用過(guò) TableView 嗎愉老,平時(shí)怎么解決 TableView 滑動(dòng)卡頓問(wèn)題的?
14焰盗、談?wù)剬?duì)多線程的使用和理解咒林?
15、項(xiàng)目中遇到過(guò)abort()嗎澎粟?如何定位和解決abort()活烙?
備用:
iOS有哪幾種鎖瓣颅?比較各種鎖的優(yōu)缺點(diǎn)宫补?并給出實(shí)例場(chǎng)景判斷用哪種鎖