面試 (二) : 基礎(chǔ)篇-2

category 和 extension 的區(qū)別
? category :分類有名字羞延,類擴(kuò)展沒i有分類名字,是一種特殊的分類
? extension :分類只能擴(kuò)展方法(屬性僅僅是聲明瞻坝,并沒真正實(shí)現(xiàn))浆洗,類擴(kuò)展可以擴(kuò)展屬性、成員變量和方法

define 和 const常量有什么區(qū)別?
? define在預(yù)處理階段進(jìn)行替換蜂科,const常量在編譯階段使用
? 宏不做類型檢查曼追,僅僅進(jìn)行替換窍仰,const常量有數(shù)據(jù)類型,會(huì)執(zhí)行類型檢查
? define不能調(diào)試礼殊,const常量可以調(diào)試
? define定義的常量在替換后運(yùn)行過程中會(huì)不斷地占用內(nèi)存驹吮,而const定義的常量存儲(chǔ)在數(shù)據(jù)段只有一份copy,效率更高
? define可以定義一些簡(jiǎn)單的函數(shù)晶伦,const不可以

block和weak修飾符的區(qū)別钥屈?
? __block不管是ARC還是MRC模式下都可以使用,可以修飾對(duì)象坝辫,也可以修飾基本數(shù)據(jù)類型
? __weak只能在ARC模式下使用篷就,只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)類型
? block修飾的對(duì)象可以在block中被重新賦值近忙,weak修飾的對(duì)象不可以

static關(guān)鍵字的作用
? 函數(shù)(方法)體內(nèi) static 變量的作用范圍為該函數(shù)體竭业,該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值及舍;
? 在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問未辆,但不能被模塊外其它函數(shù)訪問;
? 在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用锯玛,這個(gè)函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi)咐柜;
? 在類中的 static 成員變量屬于整個(gè)類所擁有兼蜈,對(duì)類的所有對(duì)象只有一份拷貝;
? 在類中的 static 成員函數(shù)屬于整個(gè)類所擁有拙友,這個(gè)函數(shù)不接收 this 指針为狸,因而只能訪問類的static 成員變量

堆和棧的區(qū)別
? 從管理方式來講
○ 對(duì)于棧來講,是由編譯器自動(dòng)管理遗契,無需我們手工控制辐棒;
○ 對(duì)于堆來說,釋放工作由程序員控制牍蜂,容易產(chǎn)生內(nèi)存泄露(memory leak)
? 從申請(qǐng)大小大小方面講
○ 椦空間比較小
○ 堆控件比較大
? 從數(shù)據(jù)存儲(chǔ)方面來講
○ 棧空間中一般存儲(chǔ)基本類型鲫竞,對(duì)象的地址
○ 堆空間一般存放對(duì)象本身辐怕,block的copy等

風(fēng)格糾錯(cuò)題
? 修改后的代碼

typedef NS_ENUM(NSInteger, CYLSex)
{
CYLSexMan,
CYLSexWoman
};
@interface CYLUser : NSObject<NSCopying>
@property (nonatomic, copy, readonly) NSString *name;
@property (nonatomic, assign, readonly) NSUInteger age;
@property (nonatomic, assign, readwrite) CYLSex sex;

  • (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;
  • (instancetype)initWithName:(NSString *)name age:(NSUInteger)age;

Objective-C使用什么機(jī)制管理對(duì)象內(nèi)存?
? MRC 手動(dòng)引用計(jì)數(shù)
? ARC 自動(dòng)引用計(jì)數(shù),現(xiàn)在通常ARC
? 通過retainCount 的機(jī)制來決定對(duì)象是否需要釋放从绘。 每次 runloop 的時(shí)候寄疏,都會(huì)檢查對(duì)象的 retainCount,如果retainCount 為 0顶考,說明該對(duì)象沒有地方需要繼續(xù)使用了,可以釋放掉了

ARC通過什么方式幫助開發(fā)者管理內(nèi)存妖泄?
? 通過編譯器在編譯的時(shí)候,插入類似內(nèi)存管理的代碼

ARC是為了解決什么問題誕生的驹沿?
? 首先解釋ARC: automatic reference counting自動(dòng)引用計(jì)數(shù)
? 了解MRC的缺點(diǎn)
○ 在MRC時(shí)代當(dāng)我們要釋放一個(gè)堆內(nèi)存時(shí),首先要確定指向這個(gè)堆空間的指針都被release了
○ 釋放指針指向的堆空間蹈胡,首先要確定哪些指針指向同一個(gè)堆渊季,這些指針只能釋放一次(MRC下即誰創(chuàng)建,誰釋放罚渐,避免重復(fù)釋放)
○ 模塊化操作時(shí)却汉,對(duì)象可能被多個(gè)模塊創(chuàng)建和使用,不能確定最后由誰去釋放
○ 多線程操作時(shí)荷并,不確定哪個(gè)線程最后使用完畢
? 綜上所述合砂,MRC有諸多缺點(diǎn),很容易造成內(nèi)存泄露和壞內(nèi)存的問題源织,這時(shí)蘋果為盡量解決這個(gè)問題翩伪,從而誕生了ARC

ARC下還會(huì)存在內(nèi)存泄露嗎?
? 循環(huán)引用會(huì)導(dǎo)致內(nèi)存泄露
? Objective-C對(duì)象與CoreFoundation對(duì)象進(jìn)行橋接的時(shí)候如果管理不當(dāng)也會(huì)造成內(nèi)存泄露
? CoreFoundation中的對(duì)象不受ARC管理谈息,需要開發(fā)者手動(dòng)釋放

什么情況使用weak關(guān)鍵字缘屹,相比assign有什么不同?
? 首先明白什么情況使用weak關(guān)鍵字侠仇?
○ 在ARC中,在有可能出現(xiàn)循環(huán)引用的時(shí)候,往往要通過讓其中一端使用weak來解決,比如:delegate代理屬性轻姿,代理屬性也可使用assign
○ 自身已經(jīng)對(duì)它進(jìn)行一次強(qiáng)引用,沒有必要再強(qiáng)引用一次,此時(shí)也會(huì)使用weak,自定義IBOutlet控件屬性一般也使用weak犁珠;當(dāng)然,也可以使用strong互亮,但是建議使用weak
? weak 和assign的不同點(diǎn)
○ weak策略在屬性所指的對(duì)象遭到摧毀時(shí)犁享,系統(tǒng)會(huì)將weak修飾的屬性對(duì)象的指針指向nil,在OC給nil發(fā)消息是不會(huì)有什么問題的胳挎;如果使用assign策略在屬性所指的對(duì)象遭到摧毀時(shí)饼疙,屬性對(duì)象指針還指向原來的對(duì)象,由于對(duì)象已經(jīng)被銷毀慕爬,這時(shí)候就產(chǎn)生了野指針窑眯,如果這時(shí)候在給此對(duì)象發(fā)送消息,很容造成程序奔潰
○ assigin 可以用于修飾非OC對(duì)象,而weak必須用于OC對(duì)象

@property 的本質(zhì)是什么医窿?
? @property其實(shí)就是在編譯階段由編譯器自動(dòng)幫我們生成ivar成員變量磅甩,getter方法,setter方法
ivar姥卢、getter卷要、setter是如何生成并添加到這個(gè)類中的?
? 使用“自動(dòng)合成”( autosynthesis)
? 這個(gè)過程由編譯器在編譯階段執(zhí)行自動(dòng)合成独榴,所以編輯器里看不到這些“合成方法”(synthesized method)的源代碼
? 除了生成getter僧叉、setter方法之外,編譯器還要自動(dòng)向類中添加成員變量(在屬性名前面加下劃線棺榔,以此作為實(shí)例變量的名字)
? 為了搞清屬性是怎么實(shí)現(xiàn)的,反編譯相關(guān)的代碼,他大致生成了五個(gè)東西

該屬性的“偏移量” (offset)瓶堕,這個(gè)偏移量是“硬編碼” (hardcode),表示該變量距離存放對(duì)象的內(nèi)存區(qū)域的起始地址有多遠(yuǎn)
OBJC_IVAR_$類名$屬性名稱

方法對(duì)應(yīng)的實(shí)現(xiàn)函數(shù)
setter與getter

成員變量列表
ivar_list

方法列表
method_list

屬性列表
prop_list
○ 每次增加一個(gè)屬性症歇,系統(tǒng)都會(huì)在ivar_list中添加一個(gè)成員變量的描述
○ 在method_list中增加setter與getter方法的描述
○ 在prop_list中增加一個(gè)屬性的描述
○ 計(jì)算該屬性在對(duì)象中的偏移量
○ 然后給出setter與getter方法對(duì)應(yīng)的實(shí)現(xiàn),在setter方法中從偏移量的位置開始賦值,在getter方法中從偏移量開始取值,為了能夠讀取正確字節(jié)數(shù),系統(tǒng)對(duì)象偏移量的指針類型進(jìn)行了類型強(qiáng)轉(zhuǎn)
@protocol 和 category 中如何使用 @property
? 在protocol中使用property只會(huì)生成setter和getter方法聲明,我們使用屬性的目的,是希望遵守我協(xié)議的對(duì)象能實(shí)現(xiàn)該屬性
? category 使用 @property也是只會(huì)生成setter和getter方法聲明,如果我們真的需要給category增加屬性的實(shí)現(xiàn),需要借助于運(yùn)行時(shí)的兩個(gè)函數(shù)

objc_setAssociatedObject
objc_getAssociatedObject
@property后面可以有哪些修飾符郎笆?
? 原子性---nonatomic特質(zhì)
○ 如果不寫默認(rèn)情況為atomic(系統(tǒng)會(huì)自動(dòng)加上同步鎖,影響性能)
○ 在iOS開發(fā)中盡量指定為nonatomic忘晤,這樣有助于提高程序的性能
? 讀/寫權(quán)限---readwrite(讀寫)宛蚓、readooly (只讀)
? 內(nèi)存管理語義---assign、strong设塔、 weak凄吏、unsafe_unretained、copy
? 方法名---getter=闰蛔、setter=

@property (nonatomic, getter=isOn) BOOL on;
setter=<name>這種不常用竞思,也不推薦使用。故不在這里給出寫法
? 不常用的:nonnull,null_resettable,nullable
使用atomic一定是線程安全的嗎钞护?
? 不是盖喷,atomic的本意是指屬性的存取方法是線程安全的,并不保證整個(gè)對(duì)象是線程安全的难咕。
? 舉例:聲明一個(gè)NSMutableArray的原子屬性stuff课梳,此時(shí)self.stuff 和self.stuff = othersulf都是線程安全的距辆。但是,使用[self.stuff objectAtIndex:index]就不是線程安全的暮刃,需要用互斥鎖來保證線程安全性

@synthesize 和 @dynamic分別有什么作用
? @property有兩個(gè)對(duì)應(yīng)的詞跨算,一個(gè)是@synthesize,一個(gè)是@dynamic椭懊。如果@synthesize和@dynamic都沒寫诸蚕,那么默認(rèn)的就是@syntheszie var = _var;
? @synthesize的語義是如果你沒有手動(dòng)實(shí)現(xiàn)setter方法和getter方法,那么編譯器會(huì)自動(dòng)為你加上這兩個(gè)方法
? @dynamic告訴編譯器:屬性的setter與getter方法由用戶自己實(shí)現(xiàn)氧猬,不自動(dòng)生成(當(dāng)然對(duì)于readonly的屬性只需提供getter即可)
○ 假如一個(gè)屬性被聲明為@dynamic var背犯,然后你沒有提供@setter方法和@getter方法,編譯的時(shí)候沒問題盅抚,但是當(dāng)程序運(yùn)行到instance.var = someVar漠魏,由于缺setter方法會(huì)導(dǎo)致程序崩潰;或者當(dāng)運(yùn)行到 someVar = instance.var時(shí)妄均,由于缺getter方法同樣會(huì)導(dǎo)致崩潰柱锹。編譯時(shí)沒問題,運(yùn)行時(shí)才執(zhí)行相應(yīng)的方法丰包,這就是所謂的動(dòng)態(tài)綁定
ARC下禁熏,不顯式指定任何屬性關(guān)鍵字時(shí),默認(rèn)的關(guān)鍵字都有哪些邑彪?
? 基本數(shù)據(jù):atomic,readwrite,assign
? 普通的OC對(duì)象:atomic,readwrite,strong
@synthesize合成實(shí)例變量的規(guī)則是什么瞧毙?假如property名為foo,存在一個(gè)名為_foo的實(shí)例變量锌蓄,那么還會(huì)自動(dòng)合成新變量么升筏?
? 先回答第二個(gè)問題:不會(huì)
? @synthesize合成成員變量的規(guī)則撑柔,有以下幾點(diǎn):
○ 如果指定了成員變量的名稱,會(huì)生成一個(gè)指定的名稱的成員變量
○ 如果這個(gè)成員已經(jīng)存在了就不再生成了
○ 如果指定@synthesize foo;就會(huì)生成一個(gè)名稱為foo的成員變量瘸爽,也就是說:會(huì)自動(dòng)生成一個(gè)屬性同名的成員變量

@interface XMGPerson : NSObject

@property (nonatomic, assign) int age;

@end

@implementationXMGPerson

不加這語句默認(rèn)生成的成員變量名為_age
如果加上這一句就會(huì)生成一個(gè)跟屬性名同名的成員變量
@synthesize age;

@end
○ 如果是 @synthesize foo = _foo; 就不會(huì)生成成員變量了
在有了自動(dòng)合成屬性實(shí)例變量之后,@synthesize還有哪些使用場(chǎng)景铅忿?
? 首先的搞清楚什么情況下不會(huì)autosynthesis(自動(dòng)合成)
○ 同時(shí)重寫了setter和getter時(shí)
○ 重寫了只讀屬性的getter時(shí)
○ 使用了@dynamic時(shí)
○ 在 @protocol 中定義的所有屬性
○ 在category 中定義的所有屬性
○ 重載的屬性剪决,當(dāng)你在子類中重載了父類中的屬性,必須 使用@synthesize來手動(dòng)合成ivar
? 應(yīng)用場(chǎng)景
○ 當(dāng)你同時(shí)重寫了setter和getter時(shí)檀训,系統(tǒng)就不會(huì)生成ivar)柑潦。這時(shí)候有兩種選擇
§ 手動(dòng)創(chuàng)建ivar
§ 使用@synthesize foo = _foo;,關(guān)聯(lián)@property與ivar
○ 可以用來修改成員變量名峻凫,一般不建議這么做渗鬼,建議使用系統(tǒng)自動(dòng)生成的成員變量
怎么用 copy 關(guān)鍵字?
? NSString荧琼、NSArray譬胎、NSDictionary等等經(jīng)常使用copy關(guān)鍵字差牛,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString、NSMutableArray堰乔、NSMutableDictionary偏化,為確保對(duì)象中的屬性值不會(huì)無意間變動(dòng),應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份镐侯,保護(hù)其封裝性
? block也經(jīng)常使用copy關(guān)鍵字
○ block 使用copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內(nèi)部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).
○ 在ARC中寫不寫都行:對(duì)于 block 使用 copy 還是 strong 效果是一樣的侦讨,但是建議寫上copy,因?yàn)檫@樣顯示告知調(diào)用者“編譯器會(huì)自動(dòng)對(duì) block 進(jìn)行了 copy 操作”
用@property聲明的NSString(或NSArray苟翻,NSDictionary)經(jīng)常使用copy關(guān)鍵字韵卤,為什么?如果改用strong關(guān)鍵字袜瞬,可能造成什么問題怜俐?
? 因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用copy的目的是為了讓本對(duì)象的屬性不受外界影響,使用copy無論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本.
? 如果我們使用是strong,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性.
復(fù)制詳解
? 淺復(fù)制(shallow copy):在淺復(fù)制操作時(shí),對(duì)于被復(fù)制對(duì)象的每一層都是指針復(fù)制邓尤。
? 深復(fù)制(one-level-deep copy):在深復(fù)制操作時(shí)拍鲤,對(duì)于被復(fù)制對(duì)象,至少有一層是深復(fù)制汞扎。
? 完全復(fù)制(real-deep copy):在完全復(fù)制操作時(shí)季稳,對(duì)于被復(fù)制對(duì)象的每一層都是對(duì)象復(fù)制。
? 非集合類對(duì)象的copy與mutableCopy

[不可變對(duì)象copy] 淺復(fù)制
[不可變對(duì)象 mutableCopy] 深復(fù)制
[可變對(duì)象 copy] 深復(fù)制
[可變對(duì)象mutableCopy] 深復(fù)制
? 集合類對(duì)象的copy與mutableCopy

[不可變對(duì)象copy] 淺復(fù)制
[不可變對(duì)象mutableCopy] 單層深復(fù)制
[可變對(duì)象 copy] 單層深復(fù)制
[可變對(duì)象mutableCopy] 單層深復(fù)制
? 這里需要注意的是集合對(duì)象的內(nèi)容復(fù)制僅限于對(duì)象本身澈魄,對(duì)象元素仍然是指針復(fù)制
這個(gè)寫法會(huì)出什么問題: @property (copy) NSMutableArray *array;
? 因?yàn)閏opy策略拷貝出來的是一個(gè)不可變對(duì)象景鼠,然而卻把它當(dāng)成可變對(duì)象使用,很容易造成程序奔潰
? 這里還有一個(gè)問題痹扇,該屬性使用了同步鎖铛漓,會(huì)在創(chuàng)建時(shí)生成一些額外的代碼用于幫助編寫多線程程序,這會(huì)帶來性能問題鲫构,通過聲明nonatomic可以節(jié)省這些雖然很小但是不必要額外開銷浓恶,在iOS開發(fā)中應(yīng)該使用nonatomic替代atomic
如何讓自定義類可以用 copy 修飾符?如何重寫帶 copy 關(guān)鍵字的 setter结笨?
? 若想令自己所寫的對(duì)象具有拷貝功能包晰,則需實(shí)現(xiàn)NSCopying協(xié)議。如果自定義的對(duì)象分為可變版本與不可變版本炕吸,那么就要同時(shí)實(shí)現(xiàn)NSCopyiog與NSMutableCopying協(xié)議伐憾,不過一般沒什么必要,實(shí)現(xiàn)NSCopying協(xié)議就夠了

實(shí)現(xiàn)不可變版本拷貝

  • (id)copyWithZone:(NSZone *)zone;
    實(shí)現(xiàn)可變版本拷貝
  • (id)mutableCopyWithZone:(NSZone *)zone;
    重寫帶 copy 關(guān)鍵字的setter
  • (void)setName:(NSString *)name
    {
    _name = [name copy];
    }

+(void)load; +(void)initialize;有什么用處赫模?
? +(void)load;
○ 當(dāng)類對(duì)象被引入項(xiàng)目時(shí), runtime會(huì)向每一個(gè)類對(duì)象發(fā)送 load 消息
○ load 方法會(huì)在每一個(gè)類甚至分類被引入時(shí)僅調(diào)用一次,調(diào)用的順序:父類優(yōu)先于子類, 子類優(yōu)先于分類
○ 由于load 方法會(huì)在類被import 時(shí)調(diào)用一次,而這時(shí)往往是改變類的行為的最佳時(shí)機(jī)树肃,在這里可以使用例如method swizlling 來修改原有的方法
○ load 方法不會(huì)被類自動(dòng)繼承
? +(void)initialize;
○ 也是在第一次使用這個(gè)類的時(shí)候會(huì)調(diào)用這個(gè)方法,也就是說 initialize也是懶加載
? 總結(jié):
○ 在Objective-C中瀑罗,runtime會(huì)自動(dòng)調(diào)用每個(gè)類的這兩個(gè)方法
○ +load會(huì)在類初始加載時(shí)調(diào)用
○ +initialize會(huì)在第一次調(diào)用類的類方法或?qū)嵗椒ㄖ氨徽{(diào)用
○ 這兩個(gè)方法是可選的胸嘴,且只有在實(shí)現(xiàn)了它們時(shí)才會(huì)被調(diào)用
○ 兩者的共同點(diǎn):兩個(gè)方法都只會(huì)被調(diào)用一次

Foundation對(duì)象與Core Foundation對(duì)象有什么區(qū)別
? Foundation框架是使用OC實(shí)現(xiàn)的莉钙,Core Foundation是使用C實(shí)現(xiàn)的
? Foundation對(duì)象 和 Core Foundation對(duì)象間的轉(zhuǎn)換:俗稱橋接
○ ARC環(huán)境橋接關(guān)鍵字:

可用于Foundation對(duì)象 和Core Foundation對(duì)象間的轉(zhuǎn)換
__bridge

用于Foundation對(duì)象 轉(zhuǎn)成 Core Foundation對(duì)象
__bridge_retained

Core Foundation對(duì)象 轉(zhuǎn)成 Foundation對(duì)象
__bridge_transfer
Foundation對(duì)象 轉(zhuǎn)成 Core Foundation對(duì)象
□ 使用__bridge橋接
? 如果使用__bridge橋接,它僅僅是將strOC的地址給了strC, 并沒有轉(zhuǎn)移對(duì)象的所有權(quán),也就是說, 如果使用__bridge橋接, 那么如果strOC釋放了,strC也不能用了
? 注意:在ARC條件下,如果是使用__bridge橋接,那么strC可以不用主動(dòng)釋放, 因?yàn)锳RC會(huì)自動(dòng)管理strOC和strC

NSString *strOC1 = [NSString stringWithFormat:@"abcdefg"];
CFStringRef strC1 = (__bridge CFStringRef)strOC1;
NSLog(@"%@ %@", strOC1, strC1);

□使用__bridge_retained橋接
? 如果使用__bridge_retained橋接,它會(huì)將對(duì)象的所有權(quán)轉(zhuǎn)移給strC, 也就是說, 即便strOC被釋放了, strC也可以使用
? 注意:在ARC條件下,如果是使用__bridge_retained橋接,那么strC必須自己手動(dòng)釋放,因?yàn)闃蚪拥臅r(shí)候已經(jīng)將對(duì)象的所有權(quán)轉(zhuǎn)移給了strC,而C語言的東西不是不歸ARC管理的

NSString *strOC2 = [NSString stringWithFormat:@"abcdefg"];
CFStringRef strC2 = (__bridge_retained CFStringRef)strOC2;
CFStringRef strC2 = CFBridgingRetain(strOC2); 這一句, 就等同于上一句
CFRelease(strC2);
§ Core Foundation對(duì)象 轉(zhuǎn)成 Foundation對(duì)象

使用__bridge橋接
? 如果使用__bridge橋接,它僅僅是將strC的地址給了strOC, 并沒有轉(zhuǎn)移對(duì)象的所有權(quán)
? 也就是說如果使用__bridge橋接,那么如果strC釋放了,strOC也不能用了

CFStringRef strC3 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
NSString *strOC3 = (__bridge NSString *)strC3;
CFRelease(strC3);

使用__bridge_transfer橋接
? 如果使用__bridge_transfer橋接,它會(huì)將對(duì)象的所有權(quán)轉(zhuǎn)移給strOC, 也就是說, 即便strC被釋放了, strOC也可以使用
? 如果使用__bridge_transfer橋接, 他會(huì)自動(dòng)釋放strC, 也就是以后我們不用手動(dòng)釋放strC

CFStringRef strC4 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
NSString *strOC = (__bridge_transfer NSString *)strC;
NSString *strOC4 = CFBridgingRelease(strC4); 這一句, 就等同于上一句

MRC環(huán)境:直接強(qiáng)轉(zhuǎn)

-(void)bridgeInMRC
{
將Foundation對(duì)象轉(zhuǎn)換為Core Foundation對(duì)象筛谚,直接強(qiáng)制類型轉(zhuǎn)換即可
NSString *strOC1 = [NSString stringWithFormat:@"xxxxxx"];
CFStringRef strC1 = (CFStringRef)strOC1;
NSLog(@"%@ %@", strOC1, strC1);
[strOC1 release];
CFRelease(strC1);

將Core Foundation對(duì)象轉(zhuǎn)換為Foundation對(duì)象磁玉,直接強(qiáng)制類型轉(zhuǎn)換即可
CFStringRef strC2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
NSString *strOC2 = (NSString *)strC2;
NSLog(@"%@ %@", strOC2, strC2);
[strOC2 release];
CFRelease(strC2);
}
addObserver:forKeyPath:options:context:各個(gè)參數(shù)的作用分別是什么,observer中需要實(shí)現(xiàn)哪個(gè)方法才能獲得KVO回調(diào)驾讲?

/**

  1. self.person:要監(jiān)聽的對(duì)象
  2. 參數(shù)說明
    1> 觀察者蚊伞,負(fù)責(zé)處理監(jiān)聽事件的對(duì)象
    2> 要監(jiān)聽的屬性
    3> 觀察的選項(xiàng)(觀察新、舊值吮铭,也可以都觀察)
    4> 上下文时迫,用于傳遞數(shù)據(jù),可以利用上下文區(qū)分不同的監(jiān)聽
    /
    [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"];
    /
    *
  • 當(dāng)監(jiān)控的某個(gè)屬性的值改變了就會(huì)調(diào)用
  • @param keyPath 監(jiān)聽的屬性名
  • @param object 屬性所屬的對(duì)象
  • @param change 屬性的修改情況(屬性原來的值谓晌、屬性最新的值)
  • @param context 傳遞的上下文數(shù)據(jù)掠拳,與監(jiān)聽的時(shí)候傳遞的一致,可以利用上下文區(qū)分不同的監(jiān)聽
    */
  • (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    NSLog(@"%@對(duì)象的%@屬性改變了:%@", object, keyPath, change);
    }

KVO內(nèi)部實(shí)現(xiàn)原理
? KVO是基于runtime機(jī)制實(shí)現(xiàn)的
? 當(dāng)某個(gè)類的屬性對(duì)象第一次被觀察時(shí)纸肉,系統(tǒng)就會(huì)在運(yùn)行期動(dòng)態(tài)地創(chuàng)建該類的一個(gè)派生類溺欧,在這個(gè)派生類中重寫基類中任何被觀察屬性的setter 方法。派生類在被重寫的setter方法內(nèi)實(shí)現(xiàn)真正的通知機(jī)制
? 如果原類為Person柏肪,那么生成的派生類名為NSKVONotifying_Person
? 每個(gè)類對(duì)象中都有一個(gè)isa指針指向當(dāng)前類姐刁,當(dāng)一個(gè)類對(duì)象的第一次被觀察,那么系統(tǒng)會(huì)偷偷將isa指針指向動(dòng)態(tài)生成的派生類烦味,從而在給被監(jiān)控屬性賦值時(shí)執(zhí)行的是派生類的setter方法
? 鍵值觀察通知依賴于NSObject 的兩個(gè)方法: willChangeValueForKey: 和didChangevlueForKey:聂使;在一個(gè)被觀察屬性發(fā)生改變之前, willChangeValueForKey: 一定會(huì)被調(diào)用谬俄,這就 會(huì)記錄舊的值柏靶。而當(dāng)改變發(fā)生后,didChangeValueForKey: 會(huì)被調(diào)用溃论,繼而observeValueForKey:ofObject:change:context: 也會(huì)被調(diào)用屎蜓。
? 補(bǔ)充:KVO的這套實(shí)現(xiàn)機(jī)制中蘋果還偷偷重寫了class方法,讓我們誤認(rèn)為還是使用的當(dāng)前類蔬芥,從而達(dá)到隱藏生成的派生類

如何手動(dòng)觸發(fā)一個(gè)value的KVO
? 自動(dòng)觸發(fā)的場(chǎng)景:在注冊(cè)KVO之前設(shè)置一個(gè)初始值梆靖,注冊(cè)之后控汉,設(shè)置一個(gè)不一樣的值笔诵,就可以觸發(fā)了
? 想知道如何手動(dòng)觸發(fā),必須知道自動(dòng)觸發(fā) KVO 的原理姑子,見上面的描述
? 手動(dòng)觸發(fā)演示

@property (nonatomic, strong) NSDate *now;

  • (void)viewDidLoad
    {
    [super viewDidLoad];
    “手動(dòng)觸發(fā)self.now的KVO”乎婿,必寫。
    [self willChangeValueForKey:@"now"];
    “手動(dòng)觸發(fā)self.now的KVO”街佑,必寫谢翎。
    [self didChangeValueForKey:@"now"];
    }
    若一個(gè)類有實(shí)例變量NSString *_foo捍靠,調(diào)用setValue:forKey:時(shí),是以foo還是_foo作為key森逮?
    ? 都可以

KVC的keyPath中的集合運(yùn)算符如何使用榨婆?
? 必須用在集合對(duì)象上或普通對(duì)象的集合屬性上
? 簡(jiǎn)單集合運(yùn)算符有@avg,@count 褒侧, @max 良风, @min ,@sum
? 格式 @"@sum.age" 或 @"集合屬性.@max.age"闷供?烟央??

KVC和KVO的keyPath一定是屬性么歪脏?
? 可以是成員變量
如何關(guān)閉默認(rèn)的KVO的默認(rèn)實(shí)現(xiàn)疑俭,并進(jìn)入自定義的KVO實(shí)現(xiàn)?
? 如何自己動(dòng)手實(shí)現(xiàn)KVO
apple用什么方式實(shí)現(xiàn)對(duì)一個(gè)對(duì)象的KVO婿失?
? 此題就是問KVO的實(shí)現(xiàn)原理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钞艇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子豪硅,更是在濱河造成了極大的恐慌香璃,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舟误,死亡現(xiàn)場(chǎng)離奇詭異葡秒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嵌溢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門眯牧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赖草,你說我怎么就攤上這事学少。” “怎么了秧骑?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵版确,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我乎折,道長(zhǎng)绒疗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任骂澄,我火速辦了婚禮吓蘑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己磨镶,他們只是感情好溃蔫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琳猫,像睡著了一般伟叛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脐嫂,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天痪伦,我揣著相機(jī)與錄音,去河邊找鬼雹锣。 笑死网沾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蕊爵。 我是一名探鬼主播辉哥,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼攒射!你這毒婦竟也來了醋旦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤会放,失蹤者是張志新(化名)和其女友劉穎饲齐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咧最,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捂人,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了矢沿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滥搭。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捣鲸,靈堂內(nèi)的尸體忽然破棺而出瑟匆,到底是詐尸還是另有隱情,我是刑警寧澤栽惶,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布愁溜,位于F島的核電站,受9級(jí)特大地震影響外厂,放射性物質(zhì)發(fā)生泄漏冕象。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一酣衷、第九天 我趴在偏房一處隱蔽的房頂上張望交惯。 院中可真熱鬧次泽,春花似錦穿仪、人聲如沸席爽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽只锻。三九已至,卻和暖如春紫谷,著一層夾襖步出監(jiān)牢的瞬間齐饮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工笤昨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祖驱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓瞒窒,卻偏偏與公主長(zhǎng)得像捺僻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崇裁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • category 和 extension 的區(qū)別? category :分類有名字匕坯,類擴(kuò)展沒i有分類名字,是一種特...
    JonesCxy閱讀 297評(píng)論 0 1
  • category 和 extension 的區(qū)別 分類有名字拔稳,類擴(kuò)展沒有分類名字葛峻,是一種特殊的分類 分類只能擴(kuò)展方...
    Andyzhao閱讀 6,852評(píng)論 1 58
  • 一、category 和 extension 的區(qū)別巴比?(分類和擴(kuò)展的區(qū)別) 1术奖,分類有名字,類擴(kuò)展沒有名字轻绞,是一種...
    閃電迷閱讀 735評(píng)論 0 3
  • 老師在上周布置了一個(gè)課間作業(yè)腰耙,如何在一分鐘又快又準(zhǔn)確地記憶十個(gè)詞:樹,鴨子铲球,耳朵挺庞,紅旗,鉤子稼病,勺子...
    雪心168閱讀 929評(píng)論 6 3