運(yùn)行時(shí)(runtime)是OC在運(yùn)行時(shí)的一些機(jī)制和特性,包括動(dòng)態(tài)類型,動(dòng)態(tài)綁定,動(dòng)態(tài)加載。運(yùn)行時(shí)系統(tǒng)指的是實(shí)現(xiàn)OC動(dòng)態(tài)特性的底層C語言庫。
為什么說OC是動(dòng)態(tài)語言:因?yàn)樵贠C中,數(shù)據(jù)類型的確定和方法的調(diào)用都從編譯時(shí)推遲到了運(yùn)行時(shí)。動(dòng)態(tài)類型如id類型(用了id類型要做判斷isKindOfClass再去接收數(shù)據(jù)和調(diào)用方法,避免crash);動(dòng)態(tài)綁定如@selector/SEL,
(2)動(dòng)態(tài)綁定
動(dòng)態(tài)綁定(dynamic binding)貌似比較難記憶,但事實(shí)上很簡(jiǎn)單,只需記住關(guān)鍵詞@selector/SEL即可。OC跳過編譯階段,用SEL變量在運(yùn)行時(shí)動(dòng)態(tài)綁定一個(gè)方法。SEL變量是存儲(chǔ)方法編號(hào)的整數(shù),通過整數(shù)來查找方法速度更快,@selector()就是取類方法的ID。
2. 屬性( @property )與成員變量(ivar)的關(guān)系 :
屬性對(duì)成員變量擴(kuò)充了存取方法 . 屬性默認(rèn)會(huì)生成帶下劃線的成員變量 .
歷史: ?早期要手寫成員變量的存取方法, ?后來可以用 @synthesize 關(guān)鍵字自動(dòng)合成成員變量的存取方法. 現(xiàn)在用@property關(guān)鍵字就能同時(shí)生成存取方法和帶下劃線的成員變量.
?注: @dynamic 關(guān)鍵字是告訴編譯器在運(yùn)行時(shí)手動(dòng)來實(shí)現(xiàn)成員變量的存取方法 , @synthesize 是讓 Xcode 自動(dòng)生成 .
3. CoreAnimation 和 CoreGraphics這兩個(gè)框架的區(qū)別
CoreGraphics是底層繪制框架,我們實(shí)際會(huì)用到的也就是CG開頭的一些底層繪制函數(shù)和變量,這是一個(gè)純C語言框架。
QuartzCore是包含了CoreAnimation的框架,是iOS系統(tǒng)的基本渲染框架,是一個(gè)OC語言框架,是一套基于CoreGraphics的OC語言封裝,封裝出了基本渲染類CALayer。
4. 面向?qū)ο笥心男┨卣饕约澳銓?duì)這些特征的理解。
繼承:子類繼承父類, 也會(huì)把父類的屬性,方法,協(xié)議一起繼承. 可以讓類之間產(chǎn)生聯(lián)系, 簡(jiǎn)化代碼.
封裝:封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法對(duì)外隱藏,對(duì)外只公開接口。外界調(diào)用接口(方法)就能實(shí)現(xiàn)功能,但不必知道內(nèi)部如何實(shí)現(xiàn), 可以保證數(shù)據(jù)安全性, 而且更加面向?qū)ο? 我們?cè)陬愔芯帉懙姆椒ň褪菍?duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫一個(gè)類就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝。
多態(tài)性:多態(tài)性是指允許不同子類型的對(duì)象對(duì)同一消息作出不同的響應(yīng)。簡(jiǎn)單的說就是用同樣的對(duì)象引用調(diào)用同樣的方法但是做了不同的事情。分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱為前綁定),而方法重寫(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱為后綁定)。要實(shí)現(xiàn)多態(tài)需要做兩件事:1. 方法重寫(子類重寫父類中已有的或方法);2. 對(duì)象造型(用父類指針指向子類)。
抽象:抽象是將一類對(duì)象的共同特征抽象成一個(gè)類,包括數(shù)據(jù)抽象和行為抽象兩方面。只關(guān)注對(duì)象有的屬性和行為,不關(guān)注細(xì)節(jié)。
5. 為什么說OC是動(dòng)態(tài)運(yùn)行時(shí)語言?
因?yàn)樵贠C 中, 通過自身的多態(tài)特性和底層運(yùn)行時(shí)系統(tǒng), 把數(shù)據(jù)類型的確定和函數(shù)綁定由編譯時(shí)推遲到了運(yùn)行時(shí).(對(duì)比C++在編譯時(shí)就將函數(shù)名進(jìn)行綁定, OC把某些編譯時(shí)報(bào)錯(cuò)延遲到運(yùn)行時(shí)) ?簡(jiǎn)單來說, 運(yùn)行時(shí)機(jī)制使我們知道程序運(yùn)行時(shí)才確定一個(gè)對(duì)象的類型,以及調(diào)用對(duì)象的哪個(gè)方法,?
6. atomic 和 nonatomic?
1. 定義:? atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作。
3. 對(duì)比: (1)前者讀寫慢, 更安全,? 后者讀寫快, 不安全.? (2)Mac OS 用前者, iOS 用后者居多。
2. 由來: ?一種線程保護(hù)技術(shù)(加鎖, 但不絕對(duì)安全), 屬性寫值未完成時(shí), ?其他線程無法讀取,避免數(shù)據(jù)讀取錯(cuò)誤。這種機(jī)制耗性能,所以在iPhone上,如沒有使用多線程間的通訊編程,那么用nonatomic聲明屬性(OC默認(rèn)atomic是因?yàn)閙ac平臺(tái)也用OC寫)。
4. 原理: 簡(jiǎn)單來說,就是 atomic 會(huì)加一個(gè)鎖來保障線程安全,并且引用計(jì)數(shù)會(huì) +1,來向調(diào)用者保證這個(gè)對(duì)象會(huì)一直存在。假如不這樣做,如有另一個(gè)線程調(diào) setter,可能會(huì)出現(xiàn)線程競(jìng)態(tài),導(dǎo)致引用計(jì)數(shù)降到0,原來那個(gè)對(duì)象就釋放掉了。但是在這種加鎖機(jī)制下, 只能說屬性是讀/寫安全的,但并不是線程安全的,因?yàn)閯e的線程還能進(jìn)行讀寫之外的其他操作。線程安全需要開發(fā)者自己來保證。
7. 簡(jiǎn)述NotificationCenter、KVC、KVO、Delegate? 并說明它們之間的區(qū)別? (重點(diǎn))
1.?KVO(Key-Value- Observing):一對(duì)多的觀察者模式, 提供了觀察對(duì)象某一屬性變化的方法,極大簡(jiǎn)化了代碼。
2. KVC(Key-Value-Coding):是鍵值編碼, 一個(gè)對(duì)象在調(diào)用setValue的時(shí)候,檢查是否存在相應(yīng)key的set方法,存在就調(diào)用set方法, 不存在就查找_key的成員變量是否存在 --> 存在就直接賦值, 不存在就查找相同名稱的key. ? --> 存在就賦值, ?沒有就調(diào)用valueForUndefinedkey和setValue:forUndefinedKey。
3. Delegate: 直接的一對(duì)一關(guān)系。代理的目的是改變或傳遞控制鏈。允許一個(gè)類在某些特定時(shí)刻通知到其他類,而不需要獲取到那些類的指針。可以減少框架復(fù)雜度。消息的發(fā)送者(sender)告知接收者(receiver)某個(gè)事件將要發(fā)生,delegate同意然然后發(fā)送者響應(yīng)事件,delegate機(jī)制使得接收者可以改變發(fā)送者的行為。
4. Notification: 觀察者模式, 間接的多對(duì)多關(guān)系。 A(通知中心單例)發(fā)送通知,B(任意對(duì)象)收到通知開始做事情(調(diào)用新方法或者block), ?但是B并不能反過來影響A的行為。
對(duì)比:?效率肯定是delegate比NSNotification高。
delegate方法比notification更加直接,需要關(guān)注返回值,所以delegate方法往往包含should這個(gè)很傳神的詞。相反的,notification最大的特色就是不關(guān)心結(jié)果。所以notification往往用did這個(gè)詞匯。兩個(gè)模塊之間聯(lián)系不是很緊密,就用notification傳值,例如多線程之間傳值用notificaiton。
delegate只是一種較為簡(jiǎn)單的回調(diào),且主要用在一個(gè)模塊中,例如底層功能完成了,需要把一些值傳到上層去,就事先把上層的函數(shù)通過delegate傳到底層,然后在底層call這個(gè)delegate,它們都在一個(gè)模塊中,完成一個(gè)功能,例如說 NavgationController 從 B 界面到A 點(diǎn)返回按鈕 (調(diào)用popViewController方法),?就用delegate。
8. 懶加載
1. 懶加載:用到某個(gè)對(duì)象時(shí)再進(jìn)行初始化, 就是重寫get方法, 也叫延時(shí)加載。舉例: tableView中圖片的加載顯示, 避免內(nèi)存過高。
2. 異步加載:開啟子線程處理耗時(shí)操作,比如加載網(wǎng)絡(luò)圖片、音頻, 避免阻塞主線程使得界面卡頓。
9. OC有沒有多繼承? 沒有的話有什么替代方法?
沒有, 可以用分類和協(xié)議來代替。
protocol(協(xié)議)可以實(shí)現(xiàn)多個(gè)接口,通過實(shí)現(xiàn)多個(gè)接口可以完成多繼承;
Category(類別)一般使用分類,用Category去重寫類的方法,僅對(duì)本Category有效,不會(huì)影響到其他類與原有類的關(guān)系。
10. 分別描述分類(categories)和延展(extensions)是什么? 以及兩者的區(qū)別? 繼承和分類在實(shí)現(xiàn)中有何區(qū)別? 為什么Category只能為對(duì)象添加方法, 卻不能添加成員變量?
1. 定義:(1)分類(categories): 在沒有原類.m文件的基礎(chǔ)上, 新建分類文件給本類添加方法; (2)延展(extensions):?分類的特例, 直接在類的.m文件里給類添加私有方法和私有變量。
2. 分類和延展的區(qū)別:?延展可以添加屬性,是一個(gè)私有分類。分類只能添加方法, 添加屬性。
3. 分類和繼承在實(shí)現(xiàn)中的區(qū)別:當(dāng)類別有和本類中同名的方法, 則類別將覆蓋本類方法, 因?yàn)轭悇e具有更高的優(yōu)先級(jí)。繼承可以增加,修改刪除方法,添加屬性。
4. 分類只能為對(duì)象添加方法, 卻不能添加成員變量的原因: 如果可以添加成員變量,添加的成員變量沒有辦法初始化。
11. Objective-C有私有方法么? 私有變量呢? 如果沒有,有什么代替的方法?
沒有真正的私有方法,objective-c類里面的方法只有兩種, 類方法和對(duì)象方法。但是可以通過把方法的聲明和定義都放在.m文件中來實(shí)現(xiàn)一個(gè)表面上的私有方法,但是通過運(yùn)行時(shí)系統(tǒng)可以調(diào)用任何方法。有私有變量, 可以通過@private來修飾,或者把成員變量聲明放到.m文件中,使其成為私有變量。在Objective‐C中,所有實(shí)例變量默認(rèn)都是私有的, 所有實(shí)例方法默認(rèn)都是公有的。
12. include和#import的區(qū)別? @class和#import的區(qū)別?
(1)import指令是OC針對(duì)C中的#include指令的改進(jìn)版本, 避免交叉包涵,交叉編譯;
(2)#import鏈接了該頭文件的全部信息,包括方法和屬性,而@class只是告訴編譯器其后申明一個(gè)類,避免編譯報(bào)錯(cuò),不用關(guān)心類中細(xì)節(jié)。一般.h中用@class, .m文件中用#import。
13. Objective-C與C、C+++之間的聯(lián)系和區(qū)別?
Objective-C和C++都是C的面向?qū)ο蟮某?/b>。
Object與C++的區(qū)別主要點(diǎn):Objective-C是完全動(dòng)態(tài)的,支持在運(yùn)行時(shí)動(dòng)態(tài)類型決議(dynamic typing),動(dòng)態(tài)綁定(dynamic binding)以及動(dòng)態(tài)裝載(dynamic loading);而C++是部分動(dòng)態(tài)的,編譯時(shí)靜態(tài)綁定,通過嵌入類(多重繼承)和虛函數(shù)(虛表)來模擬實(shí)現(xiàn)。
Objective-C 在語言層次上支持動(dòng)態(tài)消息轉(zhuǎn)發(fā),其消息發(fā)送語法為 [object function]; 而且C++ 為 object->function()。 兩者的語義也不同,在 Objective-C 里是說發(fā)送消息到一個(gè)對(duì)象上,至于這個(gè)對(duì)象能不能響應(yīng)消息以及是響應(yīng)還是轉(zhuǎn)發(fā)消息都不會(huì) crash; 而在 C++ 里是說對(duì)象進(jìn)行了某個(gè)操作,如果對(duì)象沒有這個(gè)操作的話,要么編譯會(huì)報(bào)錯(cuò)(靜態(tài)綁定),要么程序會(huì) crash 掉的(動(dòng)態(tài)綁定)。
14. 目標(biāo)-動(dòng)作機(jī)制
目標(biāo):接收事件反饋的id類型的對(duì)象。在代碼中通常用target來表示目標(biāo)對(duì)象。
動(dòng)作:事件反饋將觸發(fā)的方法。動(dòng)作對(duì)象為SEL類型,代表一個(gè)方法。
SEL類型是OC語言為存儲(chǔ)方法名創(chuàng)造的變量類型。同時(shí)還創(chuàng)造了一個(gè)運(yùn)算符,用于把一個(gè)方法名轉(zhuǎn)換成一個(gè)SEL值。
SEL test = @selector(方法名);
應(yīng)用場(chǎng)景:能夠設(shè)置反饋目標(biāo)和反饋動(dòng)作的組件我們稱為具有目標(biāo)動(dòng)作回調(diào)接口的組件,如UI控件。
15. Objective-C優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn):(1).Category和Extension(實(shí)用的擴(kuò)展機(jī)制,為類添加方法和屬性);
(2). 動(dòng)態(tài)語言(動(dòng)態(tài)類型識(shí)別,動(dòng)態(tài)綁定,動(dòng)態(tài)加載功能);
(4). 方便的通過操作指針來操作對(duì)象;
(5). C語言超集,上手快,混編。
缺點(diǎn): (1).不支持命名空間(所以蘋果類庫都要帶一些奇怪的UI,NS前綴);
(3).不支持多重繼承 ;
(4).運(yùn)行時(shí)特性讓方法調(diào)用跳過編譯時(shí), 用不到編譯時(shí)優(yōu)化方法(如內(nèi)聯(lián)函數(shù)等), 影響性能。
16. C語言的函數(shù)調(diào)用和oc的消息機(jī)制有什么區(qū)別?
C語言的函數(shù)調(diào)用在編譯時(shí)就決定調(diào)用哪個(gè)函數(shù),編譯后直接按順序執(zhí)行。
OC的消息機(jī)制是一個(gè)動(dòng)態(tài)調(diào)用過程,決定調(diào)用哪個(gè)函數(shù)從編譯時(shí)延遲到運(yùn)行時(shí)。(在編譯時(shí)并不能決定真正調(diào)用哪個(gè)函數(shù)。事實(shí)證明,在編譯階段,OC可以調(diào)用任何函數(shù),即使這個(gè)函數(shù)并未實(shí)現(xiàn),只要申明過就不會(huì)報(bào)錯(cuò)。而C語言在編譯階段就會(huì)報(bào)錯(cuò)。只有在真正運(yùn)行時(shí)才會(huì)根據(jù)函數(shù)的名稱找到對(duì)應(yīng)的函數(shù)來調(diào)用。)
17. 什么是謂詞?
謂詞就是通過NSPredicate給定的邏輯條件作為約束條件,完成對(duì)數(shù)據(jù)的篩選。
18. 常見的oc數(shù)據(jù)類型哪些,和c的基本類型有啥區(qū)別?
常見的:NSInteger CGFloat NSString NSNumber NSArray NSDate
NSInteger根據(jù)32或者64位系統(tǒng)決定本身是int還是long,CGFloat根據(jù)32或者64位系統(tǒng)決定本身是float還是double
NSString NSNumber NSArray NSDate是對(duì)象,存儲(chǔ)在堆中,c語言中的char int是一定字節(jié)的內(nèi)存空間,用于存儲(chǔ)數(shù)據(jù),存儲(chǔ)在棧中。
19. id和nil代表什么?
id類型的指針可以指向任何OC對(duì)象
nil代表空值(空指針的值,0),在Objective-C中,nil對(duì)象調(diào)用任何方法表示什么也不執(zhí)行,也不會(huì)崩潰。
20. nil和NULL的區(qū)別?
nil表示對(duì)象的指針(即對(duì)象的引用)為空;
null表示指向基本數(shù)據(jù)類型變量 (即c語言變量)的指針為空
注意:在MRC中可互換,ARC中 普通指針和對(duì)象引用被嚴(yán)格限制,不能互換!
NULL是宏,是對(duì)于C語言指針而使用的,表示空指針
nil是宏,是對(duì)于Objective-C中的對(duì)象而使用的,表示對(duì)象為空
Nil是宏,是對(duì)于Objective-C中的類而使用的,表示類指向空
NSNull是類類型,是用于表示空的占位對(duì)象,與JS或者服務(wù)端的null類似的含意
21.向一個(gè)nil對(duì)象發(fā)送消息會(huì)發(fā)生什么?
向nil發(fā)送消息是有效的,只是在運(yùn)行時(shí)不會(huì)有任何作用。
如果一個(gè)方法返回值是一個(gè)對(duì)象、指針或結(jié)構(gòu)體,那么發(fā)送給nil的消息將返回0(nil),如果返回值不是上述情況,那么發(fā)送給nil的消息的返回值將是未定義的。(如果方法返回值為指針類型,其指針大小為小于或者等于sizeof(void*),float,double,long double 或者long long的整型標(biāo)量,發(fā)送給nil的消息將返回0。如果方法返回值為結(jié)構(gòu)體,正如在《Mac OS X ABI 函數(shù)調(diào)用指南》,發(fā)送給nil的消息將返回0。結(jié)構(gòu)體中各個(gè)字段的值將都是0。其他的結(jié)構(gòu)體數(shù)據(jù)類型將不是用0填充的。)
22. self.和self->的區(qū)別?
self.是調(diào)用get或者set方法;self->是直接訪問成員變量
?前者通過成員變量的存取方法取值賦值,我們可以在兩個(gè)方法中過濾不合法的訪問,保證成員變量的封裝性;
后者隨意拿到成員變量賦值,不安全。而且后者對(duì)成員變量的訪問,要求成員變量是@public的,那么就暴露給外界了,也不安全。
23. 類方法和對(duì)象方法的區(qū)別和聯(lián)系?
類方法 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 實(shí)例方法
屬于類對(duì)象 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?屬于實(shí)例對(duì)象
只能類對(duì)象調(diào)用 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 只能實(shí)例對(duì)象調(diào)用
self指類對(duì)象 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??self指實(shí)例對(duì)象
類方法不能訪問成員變量 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 實(shí)例方法可以訪問成員變量
內(nèi)部不可直接調(diào)用對(duì)象方法(創(chuàng)建對(duì)象再調(diào)用) ? ? ? ? ? ? 內(nèi)部可直接調(diào)用類方法(通過類名)
24. _block/_weak修飾符區(qū)別?
(1)_block在arc和mrc環(huán)境下都能用,_weak只能在arc環(huán)境下使用。
(2)_block能修飾對(duì)象和基本數(shù)據(jù)類型,_weak只能修飾對(duì)象。
(3)_block修飾的對(duì)象可以在block中重新賦值,_weak不行。
25. init和initWithObjc區(qū)別(語法)?
都是構(gòu)造方法,后者給屬性賦值。
26、@property的本質(zhì)是什么?ivar、getter、setter是如何生成并添加到這個(gè)類中的?
(1)@property的本質(zhì):@property = ivar(實(shí)例變量) + ?getter/setter(存取方法)。【“屬性” (property)有兩大概念:ivar(實(shí)例變量)、存取方法(access method = getter + setter)】;
(2)ivar、getter、setter如何生成并添加到類中:
我們寫上@property + 屬性名,編譯器根據(jù)屬性名自動(dòng)合成帶下劃線的ivar和getter/setter方法,(默認(rèn)為@synthesize propertyName = _propertyName);
(3)拓展:1.?手寫@synthesize 屬性名 = _zhangsan,可以給成員變量改名成_zhangsan(一般不這么瞎搞,應(yīng)保持系統(tǒng)默認(rèn)做法);2. 手寫getter/setter方法,則不會(huì)有生成成員變量。
27. 這個(gè)寫法會(huì)出什么問題:@property (copy) NSMutableArray *array ?
第一, 沒注明nonatomic,會(huì)影響性能。(沒有指明為nonatomic,就是默認(rèn)的atomic原子操作,會(huì)在創(chuàng)建屬性時(shí)生成一些額外的代碼用于加鎖,保證線程安全,這會(huì)帶來性能問題。通過聲明nonatomic可以節(jié)省這些雖然很小但是不必要額外開銷。iOS中幾乎都是使用nonatomic來聲明的,因?yàn)槭褂胊tomic也并不能保證絕對(duì)的線程安全,對(duì)于要絕對(duì)保證線程安全的操作,還需要使用更高級(jí)的方式來處理,比如NSSpinLock、@syncronized等)
第二,copy一個(gè)可變數(shù)組將會(huì)得到一個(gè)不可變數(shù)組。如果對(duì)copy出來的數(shù)組進(jìn)行增刪改操作,會(huì)crash。
28. @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。
29. @property中有哪些屬性關(guān)鍵字?
原子性 (atomic,nonatomic)
讀寫(readwrite, readonly)
內(nèi)存管理(assign, strong, weak, unsafe_unretained,copy)
重命名 getter、setter
30. 如何訪問并修改一個(gè)類的私有屬性?
通過KVC獲取,通過runtime訪問并修改私有屬性。
Objective-C 中,meta-class 指的是什么?
meta-class 是類對(duì)象的類,為這個(gè)Class類存儲(chǔ)類方法,當(dāng)一個(gè)類發(fā)送消息時(shí),就去這個(gè)類對(duì)應(yīng)的meta-class中查找那個(gè)消息,每個(gè)Class都有不同的meta-class,所有的meta-class都使用基類的meta-class(假如類繼承NSObject,那么他所對(duì)應(yīng)的meta-class也是NSObject)作為他們的類
對(duì)于語句NSString *obj = [[NSData alloc] init]; ,編譯時(shí)和運(yùn)行時(shí)obj分別是什么類型?
編譯時(shí)是NSString類型 ,運(yùn)行時(shí)是NSData類型.
@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 = var 時(shí),由于缺 getter 方法同樣會(huì)導(dǎo)致崩潰。編譯時(shí)沒問題,運(yùn)行時(shí)才執(zhí)行相應(yīng)的方法,這就是所謂的動(dòng)態(tài)綁定。
NSString 的時(shí)候用copy和strong的區(qū)別?
簡(jiǎn)言之,copy修飾NSString會(huì)多一次判斷,strong則不會(huì),如果NSString很多,性能差。(OC中NSString為不可變字符串的時(shí)候,用copy和strong都是只分配一次內(nèi)存,但是如果用copy的時(shí)候,需要先判斷字符串是否是不可變字符串,如果是不可變字符串,就不再分配空間,如果是可變字符串才分配空間。如果程序中用到NSString的地方特別多,每一次都要先進(jìn)行判斷就會(huì)耗費(fèi)性能,影響用戶體驗(yàn),用strong就不會(huì)再進(jìn)行判斷,所以,不可變字符串可以直接用strong。)
NSArray、NSSet、NSDictionary與NSMutableArray、NSMutableSet、NSMutableDictionary的特性和作用(遇到copy修飾產(chǎn)生的變化)
特性:
NSArray表示不可變數(shù)組,元素有序,只能存對(duì)象,可通過下標(biāo)訪問元素,而且元素類型可以不一樣,但是不能進(jìn)行增、刪、改操作;NSMutableArray是可變數(shù)組,能進(jìn)行增、刪、改操作。通過索引查詢值很快,但是插入、刪除等效率很低。(數(shù)組用于處理一組有序的數(shù)據(jù)集,比如常用的tableview的dataSource要求有序,可通過索引直接訪問,效率高。)
NSSet表示不可變集合,具有確定性、互異性、無序性的特點(diǎn),只能訪問而不能修改集合;NSMutableSet表示可變集合,可以對(duì)集合進(jìn)行增、刪、改操作。集合通過值查詢很快,插入、刪除操作極快。
集合在iOS開發(fā)中比較少用,多點(diǎn)觸控時(shí)的多個(gè)UITouch對(duì)象就是NSSet形式存在的。
字典是鍵值對(duì)數(shù)據(jù)集,值是無序的。JSON轉(zhuǎn)字典,字典轉(zhuǎn)模型就是其中一種應(yīng)用。
weak和assign區(qū)別?
weak:一般修飾控件,代表指向?qū)ο蟮氖侨踔羔槪糜?jì)數(shù)不會(huì)+1,指向的對(duì)象銷毀時(shí)指針自動(dòng)清空;
assign,一般修飾int float double等基本數(shù)據(jù)類型,引用計(jì)數(shù)不會(huì)+1,指向的對(duì)象銷毀時(shí)指針不會(huì)清空;
frame和bounds的區(qū)別?
frame以父控件左上角為坐標(biāo)原點(diǎn),bounds以自己的左上角為坐標(biāo)原點(diǎn)。兩者都是描述一塊區(qū)域的可視范圍。前者決定自己在父控件中的位置,后者決定子控件在自己中的位置。