1.講一下atomic的實(shí)現(xiàn)機(jī)制赘理;為什么不能保證絕對(duì)的線程安全
答:atomic只能保證setter和getter的原子屬性,當(dāng)多條線程操作時(shí)(A,B線程)
A線程在進(jìn)行讀操作,B線程在進(jìn)行寫操作,這時(shí)候A可能讀的是B操作的值悬钳,
如果還有一個(gè)C線程骚露,C線程同時(shí)釋放了該屬性趾代,這時(shí)候這個(gè)屬性被Release
導(dǎo)致奔潰冀瓦。
2伴奥、分類和擴(kuò)展有什么區(qū)別?可以分別用來做什么翼闽?分類有哪些局限性拾徙?分類的結(jié)構(gòu)體里面有哪些成員?
個(gè)人覺得分類和擴(kuò)展的不同在于
1感局、分類只可以擴(kuò)展方法(但可以通過動(dòng)態(tài)去添加尼啡,實(shí)現(xiàn)get/set方法),擴(kuò)展可以擴(kuò)展方法和屬性询微。
2玄叠、擴(kuò)展在.h文件中聲明的是公開方法,需要去實(shí)現(xiàn)
(雖然不實(shí)現(xiàn)也沒問題拓提,但你聲明出來干啥读恃?萬一別人調(diào)用了呢?代态?埋坑等人踩寺惫??蹦疑?)西雀,在.m文件中聲明是私有的。
3歉摧、分類可以在不修改原來類的基礎(chǔ)上艇肴,為一個(gè)類擴(kuò)展方法。而且最有用的是可以擴(kuò)展系統(tǒng)類叁温,提供了不少便利再悼;
(當(dāng)方法被多次定義導(dǎo)致沖突時(shí)候,只會(huì)執(zhí)行Targets,Build Phases,Complie Source下最下面的類(本類不包含膝但,本類是不會(huì)被執(zhí)行的))冲九。
分類和擴(kuò)展的優(yōu)缺點(diǎn):
分類
1、原則上只能增加方法(能添加屬性的的原因只是通過runtime的objc_setAssociatedObject和objc_getAssociatedObject方法添加setter/getter方法)
2跟束、方法沒被實(shí)現(xiàn)編譯器不會(huì)有任何警告莺奸,因?yàn)榉诸愂窃谶\(yùn)行時(shí)添加到類中
3、可以減少單個(gè)文件的體積
4冀宴、把不同功能組織到不同的Category里
5灭贷、可以由多個(gè)開發(fā)者共同完成一個(gè)類
6、可以按需加載想要的category
7略贮、聲明私有方法
缺點(diǎn)
(1)無法向類中添加新的實(shí)例變量甚疟。
(2)名稱沖突仗岖,即當(dāng)類別中的方法與原始類方法名稱沖突時(shí),類別具有更高的優(yōu)先級(jí)古拴。
(3)如果多個(gè)分類中都有和原有類中同名的方法, 那么調(diào)用該方法的時(shí)候執(zhí)行誰由編譯器決定;編譯器會(huì)執(zhí)行最后一個(gè)參與編譯的分類中的方法
擴(kuò)展
1真友、不僅可以增加方法黄痪,還可以增加實(shí)例變量(或者屬性),只是該實(shí)例變量默認(rèn)是@private類型的(使用范圍只能在自身類盔然,而不是子類或其他地方)
2桅打、聲明的方法沒被實(shí)現(xiàn),編譯器會(huì)報(bào)警愈案,因?yàn)閿U(kuò)展是在編譯階段被添加到類中
3挺尾、定義在 .m 文件中的擴(kuò)展方法為私有的,定義在 .h 文件(頭文件)中的擴(kuò)展方法為公有的站绪。擴(kuò)展是在 .m 文件中聲明私有方法的非常好的方式
分類結(jié)構(gòu)體:
struct category_t {
const char *name; // 類的名字
classref_t cls;// 類本身
struct method_list_t *instanceMethods; // 對(duì)象方法
struct method_list_t *classMethods; // 類方法
struct protocol_list_t *protocols; // 協(xié)議
struct property_list_t *instanceProperties; // category中添加的所有屬性
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};
我們發(fā)現(xiàn)分類結(jié)構(gòu)體中是不存在成員變量的遭铺,因此分類中是不允許添加成員變量的。分類中添加的屬性并不會(huì)幫助我們自動(dòng)生成成員變量恢准,只會(huì)生成get set方法的聲明魂挂,需要我們自己去實(shí)現(xiàn)。
iOS 中內(nèi)省的幾個(gè)方法馁筐?class方法和objc_getClass方法有什么區(qū)別?
內(nèi)省方法
判斷對(duì)象類型:
-(BOOL) isKindOfClass: 判斷是否是這個(gè)類或者這個(gè)類的子類的實(shí)例
-(BOOL) isMemberOfClass: 判斷是否是這個(gè)類的實(shí)例
判斷對(duì)象or類是否有這個(gè)方法
-(BOOL) respondsToSelector: 判讀實(shí)例是否有這樣方法
+(BOOL) instancesRespondToSelector: 判斷類是否有這個(gè)方法
object_getClass:獲得的是isa的指向
self.class:當(dāng)self是實(shí)例對(duì)象的時(shí)候涂召,返回的是類對(duì)象,否則則返回自身敏沉。
類方法class果正,返回的是self,所以當(dāng)查找meta class時(shí)盟迟,需要對(duì)類對(duì)象調(diào)用object_getClass方法
離屏渲染
On-Screen Rendering 在屏渲染
意為當(dāng)前屏幕渲染秋泳,指的是GPU的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)中進(jìn)行的
Off——Screen Rendering 離屏渲染
意為離屏渲染,指的是GPU在當(dāng)前屏幕緩沖區(qū)外新開辟一個(gè)緩沖區(qū)進(jìn)行渲染操作
當(dāng)我們?cè)谠O(shè)置某一些UI視圖的圖層屬性攒菠,指令為位于合成之前轮锥,不能直接顯示的時(shí)候,那就觸發(fā)了離屏渲染要尔。典型的比如說舍杜,我們?cè)O(shè)置視圖的圓角屬性,包括一些蒙層赵辕,陰影等等既绩。
觸發(fā)場(chǎng)景:
·設(shè)置圓角。maskToBounds 同時(shí)設(shè)置
·圖層蒙版
·陰影
·光柵化
在觸發(fā)離屏渲染的時(shí)候还惠,會(huì)增加GPU的工作量饲握,而增加GPU的工作量很可能會(huì)導(dǎo)致GPU和CPU的工作總耗時(shí)超出了16.7ms,即屏幕的FPS小于60,從而導(dǎo)致UI的掉幀或卡頓,所以要避免離屏渲染救欧。(不在當(dāng)前屏幕進(jìn)行渲染衰粹,而是重新開了一個(gè)緩沖區(qū)進(jìn)行渲染)
ipa包處理查看
ipa包改成zip后綴可以解壓包體,看到包體內(nèi)容笆怠,里面可以看到自己包體的靜態(tài)庫(kù)以及自己添加的動(dòng)態(tài)庫(kù)還有資源文件 系統(tǒng)的動(dòng)態(tài)庫(kù)是看不見的铝耻,是多個(gè)應(yīng)用共享的。
一些小tips點(diǎn):
局部變量在方法結(jié)束后就被釋放了
static修飾的變量(無論是局部還是全局變量)只會(huì)被初始化一次蹬刷,且要到程序退出后才會(huì)釋放
static能延長(zhǎng)變量的生命周期瓢捉,但是不能改變變量的作用域
static修飾的全局變量就不能被外部訪問了,只能該文件訪問
extern能訪問其他文件中定義的全局變量办成。
觸摸事件傳遞
觸摸事件傳遞:
UIApplication -》window -》尋找處理事件最合適的view -》事件順著響應(yīng)者鏈條向上傳遞(調(diào)用控件的touches方法來作具體的事件處理touchesBegan…touchesMoved…touchedEnded)
(如果父視圖不能接受觸摸事件泡态,那么子控件就不可能接受觸摸事件)
參考:http://www.reibang.com/p/2e074db792ba
Category(類別)、 Extension(擴(kuò)展)和繼承的區(qū)別
區(qū)別:分類有名字迂卢,類擴(kuò)展沒有分類名字某弦,是一種特殊的分類
2.分類只能擴(kuò)展方法(屬性僅僅是聲明,并沒有真正實(shí)現(xiàn))而克,類擴(kuò)展可以擴(kuò)展屬性刀崖,成員變量和方法。但是這個(gè)方法必須實(shí)現(xiàn)拍摇,多人開發(fā)時(shí)候不實(shí)現(xiàn)這個(gè)深坑
kvc底層實(shí)現(xiàn)
當(dāng)一個(gè)對(duì)象調(diào)用setValue方法時(shí)亮钦,方法內(nèi)部做以下操作:
1.檢查是否存在相應(yīng)的key的set方法,如果存在充活,就調(diào)用set方法
2.如果set方法不存在蜂莉,就會(huì)查找與key相同名稱并且?guī)聞澗€的成員變量,如果有混卵,則直接給成員變量賦值映穗。
3.如果沒有找到_key,就會(huì)查找相同名稱的屬性key,如果有就直接賦值幕随。
4.如果還沒找到蚁滋,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法。
ViewController生命周期
按照?qǐng)?zhí)行順序排列:
1. initWithCoder:通過nib文件初始化時(shí)觸發(fā)赘淮。
2. awakeFromNib:nib文件被加載的時(shí)候辕录,會(huì)發(fā)生一個(gè)awakeFromNib的消息到nib文件中的每個(gè)對(duì)象。
3. loadView:開始加載視圖控制器自帶的view梢卸。
4. viewDidLoad:視圖控制器的view被加載完成走诞。
5. viewWillAppear:視圖控制器的view將要顯示在window上。
6. updateViewConstraints:視圖控制器的view開始更新AutoLayout約束蛤高。
7. viewWillLayoutSubviews:視圖控制器的view將要更新內(nèi)容視圖的位置蚣旱。
8. viewDidLayoutSubviews:視圖控制器的view已經(jīng)更新視圖的位置碑幅。
9. viewDidAppear:視圖控制器的view已經(jīng)展示到window上。
10. viewWillDisappear:視圖控制器的view將要從window上消失塞绿。
11. viewDidDisappear:視圖控制器的view已經(jīng)從window上消失沟涨。
GCD 和 NSOperation 都是用于實(shí)現(xiàn)多線程:
GCD 基于C語言的底層API,GCD主要與block結(jié)合使用异吻,代碼簡(jiǎn)潔高效裹赴。
NSOperation 屬于Objective-C類,是基于GCD更高一層的封裝涧黄。復(fù)雜任務(wù)一般用NSOperation實(shí)現(xiàn)篮昧。
堆和棧的區(qū)別:
對(duì)于棧來講赋荆,是由編譯器自動(dòng)管理笋妥,無需我們手工控制,在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)窄潭,是一塊連續(xù)的內(nèi)存的區(qū)域春宣。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在WINDOWS下嫉你,棧的大小是2M(也有的說是1M月帝,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過棧的剩余空間時(shí)幽污,將提示overflow嚷辅。因此,能從棧獲得的空間較小
對(duì)于堆來說距误,釋放工作由程序員控制簸搞,容易產(chǎn)生內(nèi)存泄露。堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu)准潭,是不連續(xù)的內(nèi)存區(qū)域趁俊。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑[內(nèi)存地址](https://www.baidu.com/s?wd=%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd)的,自然是不連續(xù)的刑然,而鏈表的遍歷方向是由低地址向高地址寺擂。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見泼掠,堆獲得的空間比較靈活怔软,也比較大。