iOS面試

面向對象的三大特性:封裝、繼承勇边、多態(tài)

OC內存管理

_strong

?? 引用計數(shù)器來控制對象的生命周期峭判。

_weak

?? 不會持有對象,防止循環(huán)引用棍好。

_autorelasing

?? 自動釋放池仗岸。

ARC

ARC會自動插入retain和release語句。ARC編譯器有兩部分借笙,分別是前端編譯器和優(yōu)化器扒怖。

1. 前端編譯器

前端編譯器會為“擁有的”每一個對象插入相應的release語句。如果對象的所有權修飾符是__strong提澎,那么它就是被擁有的姚垃。如果在某個方法內創(chuàng)建了一個對象,前端編譯器會在方法末尾自動插入release語句以銷毀它盼忌。而類擁有的對象(實例變量/屬性)會在dealloc方法內被釋放积糯。事實上,你并不需要寫dealloc方法或調用父類的dealloc方法谦纱,ARC會自動幫你完成一切看成。此外,由編譯器生成的代碼甚至會比你自己寫的release語句的性能還要好跨嘉,因為編輯器可以作出一些假設川慌。在ARC中,沒有類可以覆蓋release方法祠乃,也沒有調用它的必要梦重。ARC會通過直接使用objc_release來優(yōu)化調用過程。而對于retain也是同樣的方法亮瓷。ARC會調用objc_retain來取代保留消息琴拧。

2. ARC優(yōu)化器

雖然前端編譯器聽起來很厲害的樣子,但代碼中有時仍會出現(xiàn)幾個對retain和release的重復調用嘱支。ARC優(yōu)化器負責移除多余的retain和release語句蚓胸,確保生成的代碼運行速度高于手動引用計數(shù)的代碼。

runtime 中除师,SELIMP的區(qū)別

答:SEL:類成員的方法指針沛膳,不同于C中的函數(shù)指針,SEL只是一個編號汛聚。?

? ? ? ? IMP:函數(shù)指針锹安,指向我們定義的函數(shù)。

? ? ? ? 每一個繼承于NSObject的類都能自動獲得runtime的支持。在這樣的一個類中八毯,有一個isa指針搓侄,指向該類定義的數(shù)據(jù)結構體,這個結構體是由編譯器編譯時為類(需繼承于NSObject)創(chuàng)建的.在這個結構體中有包括了指向其父類類定義的指針以及 Dispatch table. Dispatch table是一張SEL和IMP的對應表。(http://blog.csdn.net/fengsh998/article/details/8614486)

? ? 也就是說方法編號SEL最后還是要通過Dispatch table表尋找到對應的IMP话速,IMP就是一個函數(shù)指針讶踪,然后執(zhí)行這個方法

事件的傳遞與響應:

1、當一個事件發(fā)生后泊交,事件會從父控件傳給子控件乳讥,也就是說由UIApplication -> UIWindow -> UIView -> initial view,以上就是事件的傳遞,也就是尋找最合適的view的過程廓俭。

2云石、接下來是事件的響應。首先看initial view能否處理這個事件研乒,如果不能則會將事件傳遞給其上級視圖(inital view的superView)汹忠;如果上級視圖仍然無法處理則會繼續(xù)往上傳遞;一直傳遞到視圖控制器view controller雹熬,首先判斷視圖控制器的根視圖view是否能處理此事件宽菜;如果不能則接著判斷該視圖控制器能否處理此事件,如果還是不能則繼續(xù)向上傳 遞竿报;(對于第二個圖視圖控制器本身還在另一個視圖控制器中铅乡,則繼續(xù)交給父視圖控制器的根視圖,如果根視圖不能處理則交給父視圖控制器處理)烈菌;一直到 window阵幸,如果window還是不能處理此事件則繼續(xù)交給application處理,如果最后application還是不能處理此事件則將其丟棄

3芽世、在事件的響應中挚赊,如果某個控件實現(xiàn)了touches…方法,則這個事件將由該控件來接受济瓢,如果調用了[supertouches….];就會將事件順著響應者鏈條往上傳遞咬腕,傳遞給上一個響應者;接著就會調用上一個響應者的touches….方法葬荷。

事件的傳遞和響應的區(qū)別:

? ? 事件的傳遞是從上到下(父控件到子控件),事件的響應是從下到上(順著響應者鏈條向上傳遞:子控件到父控件纽帖。

?1宠漩、事件傳遞查找到用戶點擊的視圖(C)后,當前視圖(C)是否能夠響應觸摸事件(處理觸摸事件)懊直。

?2扒吁、如果不能響應觸摸事件,則交給當前視圖(C)的父視圖來響應室囊。

?3雕崩、如果父視圖不能響應觸摸事件魁索,則由父視圖的父視圖來響應。

?4盼铁、若最后誰都不對此觸摸事件做處理粗蔚,則丟棄此事件。

hitTest:用來找出最適合響應事件的視圖饶火。

1鹏控、首先在當前視圖的hitTest方法中調用pointInside方法判斷觸摸點是否在當前視圖內

2、若pointInside方法返回NO肤寝,說明觸摸點不在當前視圖內当辐,則當前視圖的hitTest返回nil,該視圖不處理該事件

3鲤看、若pointInside方法返回YES缘揪,說明觸摸點在當前視圖內,則從最上層的子視圖開始(即從subviews數(shù)組的末尾向前遍歷)义桂,遍歷當前視圖的所有子視圖找筝,調用子視圖的hitTest方法重復步驟1-3

4、直到有子視圖的hitTest方法返回非空對象或者全部子視圖遍歷完畢

5澡刹、若第一次有子視圖的hitTest方法返回非空對象呻征,則當前視圖的hitTest方法就返回此對象,處理結束

6罢浇、若所有子視圖的hitTest方法都返回nil陆赋,則當前視圖的hitTest方法返回當前視圖本身,最終由該對象處理觸摸事件

http://www.reibang.com/p/4fea8fa60d75

屬性的實質是什么嚷闭?包括哪幾個部分攒岛?屬性默認的關鍵字都有哪些?@dynamic關鍵字和@synthesize關鍵字是用來做什么的胞锰?

屬性的實質:@property = ivar + getter + setter -> 實例變量+get方法+set方法,也就是說使用@property 系統(tǒng)會自動生成 成員變量以及setter和getter方法;

?? ? 在普通的OC對象中,@property就是編譯其自動幫我們生成一個私有的成員變量和setter與getter方法的聲明和實現(xiàn)灾锯。

包括:實例變量+get方法+set方法

@synthesize@dynamic分別有什么作用?

答:

@property有兩個對應的詞嗅榕,一個是@synthesize顺饮,一個是@dynamic。如果@synthesize和@dynamic都沒寫凌那,那么默認的就是@syntheszie var = _var;

@synthesize的語義是如果你沒有手動實現(xiàn)setter方法和getter方法兼雄,那么編譯器會自動為你加上這兩個方法。

@dynamic告訴編譯器,屬性的setter與getter方法由用戶自己實現(xiàn)帽蝶,不自動生成赦肋。(當然對于readonly的屬性只需提供getter即可)。假如一個屬性被聲明為@dynamic var,然后你沒有提供@setter方法和@getter方法佃乘,編譯的時候沒問題囱井,但是當程序運行到instance.var =someVar,由于缺setter方法會導致程序崩潰趣避;或者當運行到 someVar = var時庞呕,由于缺getter方法同樣會導致崩潰。編譯時沒問題鹅巍,運行時才執(zhí)行相應的方法千扶,這就是所謂的動態(tài)綁定。

tableview

tableview的delegate和datasource執(zhí)行順序

1.//有多少列?

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

2.//cell 頁眉高度?

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

3.//cell頁腳高度?

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section

4.//每組有多少行?

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

5.//cell高度?

-(CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath

6.//布局UItableviewcell?

-(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

UITableViewCell的可重用機制

1.使用可重用機制創(chuàng)建cell(系統(tǒng))

1)定義可重用標識

2)從可重用隊列中取出cell

3)若隊列中無可用cell骆捧,利用alloc澎羞,init新建cell

原理

在UITableView的頭文件中有visibleCells,存放當前顯示的的cells

@property (nonatomic,readonly)NSArray<__kindofUITableViewCell *> *visibleCells;

當需要更新顯示數(shù)據(jù)時敛苇,dequeueReusableCellWithIdentifier會先在可重用cell隊列?reusable-cell queue中返回一個cell對象妆绞,若不存在宿稀,則返回nil邓夕;

存在的問題

重取出來的cell是有可能已經(jīng)捆綁過數(shù)據(jù)或者加過子視圖的,造成視圖疊加混亂的現(xiàn)象

解決:

1)刪除已有數(shù)據(jù)或子視圖

2)放棄了重用機制恕洲,每次根據(jù)indexPath獲取對應的cell返回来涨。

將方法:??UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIndentifier];

替換為: ?UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];?

tableView滑動為什么會卡頓图焰?

cell賦值內容時,會根據(jù)內容設置布局蹦掐,也就可以知道cell的高度技羔,若有1000行,就會調用1000次 cellForRow方法卧抗,而我們對cell的處理操作藤滥,都是在這個方法中賦值,布局等等社裆,開銷很大拙绊。

優(yōu)化總結

1.提前計算并緩存好高度,因為heightForRow最頻繁的調用泳秀。

2.異步繪制标沪,遇到復雜界面,性能瓶頸時嗜傅,可能是突破口谨娜。

3.滑動時按需加載,這個在大量圖片展示磺陡,網(wǎng)絡加載時,很管用。(SDWebImage已經(jīng)實現(xiàn)異步加載)币他。

4.重用cells坞靶。

5.如果cell內顯示得內容來自web,使用異步加載蝴悉,緩存結果請求彰阴。

6.少用或不用透明圖層,使用不透明視圖拍冠。

7.盡量使所有的view opaque尿这,包括cell本身。

8.減少subViews

9.少用addView給cell動態(tài)添加view庆杜,可以初始化的時候就添加射众,然后通過hide控制是否顯示。

Objective-C Block 有三種類型:

1晃财、NSGlobalBlock

? ? block內部沒有引用外部變量的 Block 類型都是 NSGlobalBlock 類型叨橱,存儲于全局數(shù)據(jù)區(qū),由系統(tǒng)管理其內存断盛,retain罗洗、copy、release操作都無效钢猛。

2伙菜、NSStackBlock

? ? block內部引用外部變量,retain命迈、release 操作無效贩绕,存儲于棧區(qū),變量作用域結束時躺翻,其被系統(tǒng)自動釋放銷毀丧叽。MRC 環(huán)境下,[[mutableAarry addObject: blockA]公你,(在arc中不用擔心此問題踊淳,因為arc中會默認將實例化的block拷貝到堆上)在其所在作用域結束也就是函數(shù)出棧后,從mutableAarry中取到的blockA已經(jīng)被回收陕靠,變成了野指針迂尝。正確的做法是先將blockA copy到堆上,然后加入數(shù)組剪芥。支持copy垄开,copy之后生成新的NSMallocBlock類型對象。

3税肪、NSMallocBlock

? ? 如上例中的_block溉躲,[blockA copy]操作后變量類型變?yōu)?NSMallocBlock榜田,支持retain、release锻梳,雖然 retainCount 始終是 1箭券,但內存管理器中仍然會增加、減少計數(shù)疑枯,當引用計數(shù)為零的時候釋放(可多次retain辩块、release 操作驗證)。copy之后不會生成新的對象荆永,只是增加了一次引用废亭,類似retain,盡量不要對Block使用retain操作具钥。

http://www.cocoachina.com/ios/20150601/11970.html

runloop

? ? 一個 RunLoop 包含若干個 Mode豆村,每個 Mode 又包含若干個 Source/Timer/Observer。每次調用 RunLoop 的主函數(shù)時氓拼,只能指定其中一個 Mode你画,這個Mode被稱作 CurrentMode。如果需要切換 Mode桃漾,只能退出 Loop坏匪,再重新指定一個 Mode 進入。這樣做主要是為了分隔開不同組的 Source/Timer/Observer撬统,讓其互不影響适滓。

作用:

1、等待用戶操作

2恋追、決定處理事件

3凭迹、調用解耦

4、節(jié)省cpu時間(沒事的時候等待)

? ? 一般來講苦囱,一個線程一次只能執(zhí)行一個任務嗅绸,執(zhí)行完成后線程就會退出。如果我們需要一個機制撕彤,讓線程能隨時處理事件但并不退出鱼鸠,所以,RunLoop 實際上就是一個對象羹铅,這個對象管理了其需要處理的事件和消息蚀狰,并提供了一個入口函數(shù)來執(zhí)行上面 Event Loop 的邏輯。線程執(zhí)行了這個函數(shù)后职员,就會一直處于這個函數(shù)內部 "接受消息->等待->處理" 的循環(huán)中麻蹋,直到這個循環(huán)結束(比如傳入 quit 的消息),函數(shù)返回焊切。

NSTimerRunloop的關系

?? ? 我們前面做演示的代碼創(chuàng)建的NSTimer會默認為我們添加到Runloop的NSDefaultRunLoopMode中扮授,而且由于是在主線程中芳室,所以Runloop是開啟的,不需要我們手動打開刹勃。

? ? 在我們進行多線程編程時渤愁,所有的Source都需要添加到Runloop中才能生效,對于我們的NSTimer當然也需要添加到Runloop中才能生效深夯,NSTimer也在source里。如果一個Runloop中沒有任何Source的話诺苹,會立即退出的咕晋。而主線程的Runloop在程序運行時,系統(tǒng)就已經(jīng)為我們添加了很多Source到Runloop中收奔,所以主線程的Runloop是一直存在的掌呜,我們可以通過打印MainThread中的Runloop來查看所包含的Source。

NSTimer添加到Runloop中坪哄,但是不運行

? ? 在iOS多線程中质蕉,每一個線程都有一個Runloop,但是只有主線程的Runloop默認是打開的翩肌,其他子線程也就是我們創(chuàng)建的線程的Runloop默認是關閉的模暗,需要我們手動運行。

? ? 我們可以通過[NSRunLoop currentRunLoop]來獲得當前線程的Runloop念祭,并且調用[runloop addTimer:timer forMode:NSDefaultRunLoopMode]方法將定時器添加到Runloop中兑宇,最后一定不要忘記調用Runloop的run方法將當前Runloop開啟,否則NSTimer永遠也不會運行粱坤。

http://www.reibang.com/p/32265cbb2a26

Autorelease

UIKit通過RunLoopObserver在Runloop倆次sleep間對AutoreleasePool進行pop和push隶糕,將這次loop中產(chǎn)生的Autorelease對象釋放。

AutoreleasePoolPage由雙向鏈表鏈接站玄,每個AutoreleasePoolPage所能存儲的對象有限枚驻,當一個AutoreleasePoolPage滿時會創(chuàng)建另一個AutoreleasePoolPage的對象來存放對象。

objc_autoreleasePoolPush 方法:

void *objc_autoreleasePoolPush(void) {

? ? return AutoreleasePoolPage::push();

}

它調用 AutoreleasePoolPage 的類方法 push株旷,也非常簡單:

static inline void *push() {

?? return autoreleaseFast(POOL_SENTINEL);

}

在這里會進入一個比較關鍵的方法 autoreleaseFast再登,并傳入哨兵對象 POOL_SENTINEL:

static inline id *autoreleaseFast(id obj)

{

?? AutoreleasePoolPage *page = hotPage();

?? if (page && !page->full()) {

?? ? ? return page->add(obj);

?? } else if (page) {

?? ? ? return autoreleaseFullPage(obj, page);

?? } else {

?? ? ? return autoreleaseNoPage(obj);

?? }

}

上述方法分三種情況選擇不同的代碼執(zhí)行:

hotPage 并且當前 page 不滿

調用 page->add(obj) 方法將對象添加至 AutoreleasePoolPage 的棧中

hotPage 并且當前 page 已滿

調用 autoreleaseFullPage 初始化一個新的頁

調用 page->add(obj) 方法將對象添加至 AutoreleasePoolPage 的棧中

hotPage

調用 autoreleaseNoPage 創(chuàng)建一個 hotPage

調用 page->add(obj) 方法將對象添加至 AutoreleasePoolPage 的棧中

最后的都會調用 page->add(obj) 將對象添加到自動釋放池中。

hotPage 可以理解為當前正在使用的 AutoreleasePoolPage灾常。

page->add 添加對象

autoreleaseFullPage(當前 hotPage 已滿)

autoreleaseFullPage 會在當前的 hotPage 已滿的時候調用:

static id *autoreleaseFullPage(id obj, AutoreleasePoolPage *page) {

? ? do {

? ? ? ? if (page->child) page = page->child;

? ? ? ? else page = new AutoreleasePoolPage(page);

? ? } while (page->full());

? ? setHotPage(page);

? ? return page->add(obj);

}

它會從傳入的 page 開始遍歷整個雙向鏈表霎冯,直到:

1、查找到一個未滿的 AutoreleasePoolPage

或者

2钞瀑、使用構造器傳入 parent 創(chuàng)建一個新的 AutoreleasePoolPage

在查找到一個可以使用的 AutoreleasePoolPage 之后沈撞,會將該頁面標記成 hotPage,然后調動上面分析過的 page->add 方法添加對象雕什。

autoreleaseNoPage(沒有 hotPage)

如果當前內存中不存在 hotPage缠俺,就會調用 autoreleaseNoPage 方法初始化一個 AutoreleasePoolPage

static id *autoreleaseNoPage(id obj) {

? ? AutoreleasePoolPage *page = new AutoreleasePoolPage(nil);

? ? setHotPage(page);

? ? if (obj != POOL_SENTINEL) {

? ? ? ? page->add(POOL_SENTINEL);

? ? }

? ? return page->add(obj);

}

既然當前內存中不存在 AutoreleasePoolPage显晶,就要從頭開始構建這個自動釋放池的雙向鏈表,也就是說壹士,新的 AutoreleasePoolPage 是沒有 parent 指針的磷雇。

初始化之后,將當前頁標記為 hotPage躏救,然后會先向這個 page 中添加一個 POOL_SENTINEL 對象唯笙,來確保在 pop 調用的時候,不會出現(xiàn)異常盒使。

最后崩掘,將 obj 添加到自動釋放池中。

多線程

NSThread?

? ? 這套方案是經(jīng)過蘋果封裝后的少办,并且完全面向對象的苞慢。所以你可以直接操控線程對象,非常直觀和方便英妓。但是挽放,它的生命周期還是需要我們手動管理。

–優(yōu)點:NSThread 比其他兩個輕量級蔓纠,使用簡單

–缺點:需要自己管理線程的生命周期辑畦、線程同步、加鎖贺纲、睡眠以及喚醒等航闺。線程同步對數(shù)據(jù)的加鎖會有一定的系統(tǒng)開銷

https://www.cnblogs.com/wendingding/p/3806821.html

GCD

?GCD有兩種隊列:串行隊列和并行隊列。

? 它是蘋果為多核的并行運算提出的解決方案猴誊,所以會自動合理地利用更多的CPU內核(比如雙核潦刃、四核),最重要的是它會自動管理線程的生命周期(創(chuàng)建線程懈叹、調度任務乖杠、銷毀線程),完全不需要我們管理澄成,我們只需要告訴干什么就行胧洒。同時它使用的也是 c語言,不過由于使用了 BlockSwift里叫做閉包)墨状,使得使用起來更加方便卫漫,而且靈活。

說明:同步函數(shù)不具備開啟線程的能力肾砂,無論是什么隊列都不會開啟線程列赎;異步函數(shù)具備開啟線程的能力,開啟幾條線程由隊列決定(串行隊列只會開啟一條新的線程镐确,并發(fā)隊列會開啟多條線程)

同步函數(shù)

(1)并發(fā)隊列:不會開線程

(2)串行隊列:不會開線程

異步函數(shù)

(1)并發(fā)隊列:能開啟N條線程

(2)串行隊列:開啟1條線程

https://www.cnblogs.com/zh-li/p/5140610.html

http://ios.jobbole.com/82622/

GCD死鎖的幾種情況

經(jīng)典:

NSLog(@"1"); // 任務1

dispatch_sync(dispatch_get_main_queue(), ^{

????NSLog(@"2"); // 任務2

});

NSLog(@"3"); // 任務3

分析:

1 dispatch_sync表示是一個同步線程包吝;

2 dispatch_get_main_queue表示運行在主線程中的主隊列饼煞;

3 任務2是同步線程的任務。

?? ? 首先執(zhí)行任務1诗越,這是肯定沒問題的砖瞧,只是接下來,程序遇到了同步線程嚷狞,那么它會進入等待块促,等待任務2執(zhí)行完,然后執(zhí)行任務3床未。但這是隊列褂乍,有任務來,當然會將任務加到隊尾即硼,然后遵循FIFO原則執(zhí)行任務。那么屡拨,現(xiàn)在任務2就會被加到最后只酥,任務3排在了任務2前面,

問題來了:

?? ? 任務3要等任務2執(zhí)行完才能執(zhí)行呀狼,任務2由排在任務3后面裂允,意味著任務2要在任務3執(zhí)行完才能執(zhí)行,所以他們進入了互相等待的局面哥艇【啵【既然這樣,那干脆就卡在這里吧】這就是死鎖貌踏。

NSOperationNSOperationQueue

? ? NSOperation 是蘋果公司對 GCD 的封裝十饥,完全面向對象,不需要關心線程管理祖乳,數(shù)據(jù)同步的事情逗堵,可以把精力放在自己需要執(zhí)行的操作上,所以使用起來更好理解眷昆。 大家可以看到 NSOperation 和 NSOperationQueue 分別對應 GCD 的 任務 和 隊列 蜒秤。

?? ? NSOperation 只是一個抽象類,所以不能封裝任務亚斋。但它有 2 個子類用于封裝任務作媚。分別是:NSInvocationOperation 和 NSBlockOperation 。

NSOperationQueuecancel

? ? 對于NSOperationQueue,只有add到NSOperationQueue的NSOperation才能夠執(zhí)行帅刊,關于cancel纸泡,NSOperation的cancel 并不是立即取消掉,而是過一會厚掷,?

? ? 最重要的是無論是NSOperation的cancel還是NSOperationQueue的cancelAllOperations弟灼,都不會停止正在執(zhí)行的operation级解,只能取消在隊列中等待的operation

NSOperationQueue串行隊列

? ? NSOperationQueue可以設置設置線程池中的線程數(shù),也就是并發(fā)操作數(shù)田绑。默認情況下是-1勤哗,也就是沒有限制,同時運行隊列中的全部操作掩驱。設置為1即為串行芒划,即當前只能執(zhí)行單個task,以及FIFO原則執(zhí)行完了之后再執(zhí)行下一個欧穴。

OC load方法和initialize方法的異同

+load:

?? 對于加入運行期系統(tǒng)中的每個類(class)及分類(category)來說民逼,都會調用此方法,且只會調用一次涮帘。如果分類和其所屬的類都調用了load方法拼苍,則先調用類里面的,再調用分類里的调缨。

load方法并不像普通方法那樣疮鲫,它并不遵從繼承規(guī)則。即如果某個類本身沒有l(wèi)oad方法弦叶,那么不管其超類是否實現(xiàn)load方法俊犯,系統(tǒng)都不會調用。

子類 +load 方法等父類先執(zhí)行完 +load 方法才執(zhí)行伤哺。?

分類 +load 方法會在它的主類 +load 方法之后執(zhí)行燕侠。

+initialize:

?? ? 對每個類來說,該方法會在程序首次使用該類前調用立莉,且只調用一次绢彤。它是由運行期系統(tǒng)來調用的,絕不應該通過代碼直接調用蜓耻。

initialize方法與其他消息一樣杖虾,如果某個類未實現(xiàn)它,而其超類實現(xiàn)了媒熊,就會運行超類的實現(xiàn)代碼奇适。

load和initialize之間的區(qū)別如下:

initialize是”惰性調用的”,即只有當用到了相關的類時芦鳍,才會調用嚷往。如果某個類一直都沒有使用,則其initialize方法就一直不會運行柠衅。這也就是說皮仁,應用程序無須把每個類的initialize都執(zhí)行一遍。?

這就與load不同,對于load來說贷祈,應用程序必須阻塞并等待所有類的load都執(zhí)行完趋急,才能繼續(xù)。

initialize在運行期系統(tǒng)執(zhí)行該方法時势誊,是處于正常狀態(tài)呜达,因此從運行期系統(tǒng)完整度上來講,此時可以安全使用并調用任意類中的任意方法粟耻。而且查近,運行期系統(tǒng)也能保證initialize方法一定會在“線程安全的環(huán)境(thread-safe environment)”中執(zhí)行,這就是說挤忙,只有執(zhí)行initialize的那個線程可以操作類或者類實例霜威。其他線程都要先阻塞,等著initialize執(zhí)行完册烈。?

load方法的問題在于戈泼,執(zhí)行該方法時,運行期系統(tǒng)處于“脆弱狀態(tài)(fragile state)”赏僧。在執(zhí)行子類的load方法之前矮冬,必定會執(zhí)行所有超類的load方法。

http://www.reibang.com/p/14efa33b3562

Block

// OC代碼如下

void(^myBlock)() = ^{

? ? NSLog(@"global = %d", global);

};

// 轉為C++代碼如下

void(*myBlock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, global));

將變量類型精簡之后C++代碼如下,我們發(fā)現(xiàn)Block變量實際上就是一個指向結構體__main_block_impl_0的指針

_block修飾符

__block在MRC下有兩個作用

1. 允許在Block中訪問和修改局部變量?

2. 禁止Block對所引用的對象進行隱式retain操作

__block在ARC下只有一個作用

允許在Block中訪問和修改局部變量

_block修飾符同樣可以解決block的循環(huán)引用次哈,但是有個必須執(zhí)行的過程,詳見第131頁

SDWebImage

01 設置imageView的圖片

[cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon]?

? ? placeholderImage:[UIImage imageNamed:@"placehoder"]];

// 02 設置圖片并計算下載進度

?? //下載并設置圖片

/*

?第一個參數(shù):要下載圖片的url地址

?第二個參數(shù):設置該imageView的占位圖片

?第三個參數(shù):傳一個枚舉值,告訴程序你下載圖片的策略是什么

?第一個block塊:獲取當前圖片數(shù)據(jù)的下載進度

?? ? receivedSize:已經(jīng)下載完成的數(shù)據(jù)大小

?? ? expectedSize:該文件的數(shù)據(jù)總大小

?第二個block塊:當圖片下載完成之后執(zhí)行該block中的代碼

?? ? image:下載得到的圖片數(shù)據(jù)

?? ? error:下載出現(xiàn)的錯誤信息

?? ? SDImageCacheType:圖片的緩存策略(不緩存吆录,內存緩存窑滞,沙盒緩存)

?? ? imageURL:下載的圖片的url地址

?*/

[cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon]?

? ? placeholderImage:[UIImage imageNamed:@"placehoder"]?

? ? options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {

? ? //計算當前圖片的下載進度

? ? NSLog(@"%.2f",1.0 *receivedSize / expectedSize);

} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

}];

// 03 系統(tǒng)級內存警告如何處理(面試)

// 利用通知中心觀察(監(jiān)聽系統(tǒng)警告)

? ? - UIApplicationDidReceiveMemoryWarningNotification接收到內存警告的通知

執(zhí)行 clearMemory 方法,清理內存緩存恢筝!

? ? - UIApplicationWillTerminateNotification接收到應用程序將要終止通知

執(zhí)行 cleanDisk 方法哀卫,清理磁盤緩存!(按照文件創(chuàng)建順序:從遠到近)先刪除過去的緩存,計算當前緩存的大小

maxCacheSize設置緩存的大小,默認為0

比較是否大于設定的緩存大小,如果超過,則繼續(xù)刪除,直到小于為止

? ? - UIApplicationDidEnterBackgroundNotification接收到應用程序進入后臺通知

執(zhí)行 backgroundCleanDisk 方法,后臺清理磁盤!

通過以上退出的通知,能夠保證緩存文件的大小始終在控制范圍之內冒版!

clearDisk 清空磁盤緩存嬉荆,將所有緩存目錄中的文件,全部刪除蒋失!

實際工作,將緩存目錄直接刪除,再次創(chuàng)建一個同名空目錄移剪!

04 SDWebImage默認的緩存時間是: 1周

05 SDWebImage的內存緩存是用什么實現(xiàn)的: NSCache

06 SDWebImag的最大并發(fā)數(shù)是: maxConcurrentDownloads = 6是程序固定死了,可以通過屬性進行調整

07 如何播放gif圖片

/*

5-1 把用戶傳入的gif圖片->NSData

5-2 根據(jù)該Data創(chuàng)建一個圖片數(shù)據(jù)源(NSData->CFImageSourceRef)

5-3 計算該數(shù)據(jù)源中一共有多少幀薪者,把每一幀數(shù)據(jù)取出來放到圖片數(shù)組中

5-4 根據(jù)得到的數(shù)組+計算的動畫時間-》可動畫的image

[UIImage animatedImageWithImages:images duration:duration];

*/

08 如何判斷當前圖片類型

+ (NSString *)sd_contentTypeForImageData:(NSData *)data;

09 SDWebImage是如何區(qū)分不同格式的圖像的

? ? ? ? 根據(jù)圖像數(shù)據(jù)第一個字節(jié)來判斷的纵苛!

? ? ? ? PNG:壓縮比沒有JPG高,但是無損壓縮,解壓縮性能高攻人,蘋果推薦的圖像格式取试!

? ? ? ? JPG:壓縮比最高的一種圖片格式,有損壓縮,壓縮的性能不好怀吻!最多使用的場景,照相機解

? ? ? ? GIF:序列楨動圖瞬浓,特點:只支持256種顏色!最流行的時候在1998~1999烙博,有專利的

10 圖片下載順序(先進先出 | 先進先出) 默認是先進先出

下載了圖片后為什么要解碼瑟蜈?

答:由于UIImage的imageWithData函數(shù)是每次畫圖的時候才將Data解壓成ARGB的圖像,所以在每次畫圖的時候渣窜,會有一個解壓操作铺根,這樣效率很低,但是只有瞬時的內存需求乔宿。

?? ? ? 為了提高效率通過SDWebImageDecoder將包裝在Data下的資源解壓位迂,然后畫在另外一張圖片上,這樣這張新圖片就不再需要重復解壓了详瑞。這種做法是典型的空間換時間的做法掂林。

UIView的生命周期總結

1 -[ViewController initWithCoder:]或-[ViewController initWithNibName:Bundle]:首先從歸檔文件中加載UIViewController對象。即使是純代碼坝橡,也會把nil作為參數(shù)傳給后者泻帮。

2 -[UIView awakeFromNib]:作為第一個方法的助手,方便處理一些額外的設置计寇。

3 -[ViewController loadView]:創(chuàng)建或加載一個view并把它賦值給UIViewController的view屬性

4 -[ViewController viewDidLoad]:此時整個視圖層次(view hierarchy)已經(jīng)被放到內存中锣杂,可以移除一些視圖,修改約束番宁,加載數(shù)據(jù)等

5 -[ViewController viewWillAppear:]:視圖加載完成元莫,并即將顯示在屏幕上,還沒有設置動畫,可以改變當前屏幕方向或狀態(tài)欄的風格等蝶押。

6 -[ViewController viewWillLayoutSubviews]:即將開始子視圖位置布局

7 -[ViewController viewDidLayoutSubviews]:用于通知視圖的位置布局已經(jīng)完成

8 -[ViewController viewDidAppear:]:視圖已經(jīng)展示在屏幕上踱蠢,可以對視圖做一些關于展示效果方面的修改。

9 -[ViewController viewWillDisappear:]:視圖即將消失

10 -[ViewController viewDidDisappear:]:視圖已經(jīng)消失

如果考慮UIViewController可能在某個時刻釋放整個view棋电。那么再次加載視圖時顯然會從步驟3開始茎截。因為此時的UIViewController對象依然存在。

為什么IBOutlet修飾的UIView也適用weak關鍵字赶盔?

我們將控件拖到Storyboard上稼虎,相當于創(chuàng)建了一個對象,而這個對象是加到試圖控制器的view上招刨,存放在view的subviews數(shù)組中霎俩。即我們的控件對象是屬于的view的哀军,view對其子控件之前的關系是強引用。當我們使用Outlet屬性的時候打却,這個Outlet屬性是有view來進行強引用的杉适。我們是在viewController中僅僅對其進行使用,沒有必要擁有它柳击,所以使用weak進行修飾猿推。

nonatomic和atomic的區(qū)別?atomic是絕對的線程安全么捌肴?為什么蹬叭?如果不是,那應該如何實現(xiàn)状知?

nonatomic和atomic用來決定編譯器生成的getter和setter操作是否為原子操作秽五。atomic不是絕對的線程安全。atomic的本意是指屬性的存取方法是線程安全的饥悴,并不保證整個對象是線程安全的坦喘。如:

聲明一個NSMutableArray的原子屬性stuff,此時self.stuff 和 self.stuff = otherstuff都是線程安全的西设。但是使用[self.stuff objectAtIndex:index]就不是線程安全的瓣铣。需要用互斥鎖來保證線程安全性。

NSCache

1)NSCache是蘋果官方提供的緩存類贷揽,具體使用和NSMutableDictionary類似棠笑,在AFN和SDWebImage框架中被使用來管理緩存

2)蘋果官方解釋NSCache在系統(tǒng)內存很低時,會自動釋放對象(但模擬器演示不會釋放)

? ? 建議:接收到內存警告時主動調用removeAllObject方法釋放對象

3)NSCache是線程安全的禽绪,在多線程操作中蓖救,不需要對NSCache加鎖

4)NSCache的Key只是對對象進行Strong引用,不是拷貝丐一,在清理的時候計算的是實際大小而不是引用的大小

NSCache優(yōu)于NSDictionary的幾點?

? ? NSCache勝過NSDictionary之處在于淹冰,當系統(tǒng)資源將要耗盡時库车,它可以自動刪減緩存。如果采用普通的字典樱拴,那么就要自己編寫掛鉤柠衍,在系統(tǒng)發(fā)出“低內存”通知時手工刪減緩存。

? ? NSCache并不會“拷貝”鍵晶乔,而是會“保留”它珍坊。此行為用NSDictionary也可以實現(xiàn),然而需要編寫相當復雜的代碼正罢。NSCache對象不拷貝鍵的原因在于:很多時候阵漏,鍵都是不支持拷貝操作的對象來充當?shù)摹R虼耍琋SCache不會自動拷貝鍵履怯,所以說回还,在鍵不支持拷貝操作的情況下,該類用起來比字典更方便叹洲。另外柠硕,NSCache是線程安全的,而NSDictionary則絕對不具備此優(yōu)勢运提。

description方法

http://www.reibang.com/p/08b59e425d2c

什么時候會報unrecognized selector錯誤蝗柔?

1 對象未實現(xiàn)該方法。

2 對象已經(jīng)被釋放民泵。

能否向編譯后得到的類中增加實例變量癣丧?能否向運行時創(chuàng)建的類中添加實例變量?為什么洪灯?

? ? 不能坎缭,能。

? ? 因為編譯后的類已經(jīng)注冊在 runtime 中签钩,類結構體中的 objc_ivar_list 實例變量的鏈表 和 instance_size 實例變量的內存大小已經(jīng)確定掏呼,同時runtime 會調用 class_setIvarLayout 或 class_setWeakIvarLayout 來處理 strong weak 引用。所以不能向存在的類中添加實例變量铅檩;

? ? 運行時創(chuàng)建的類是可以添加實例變量憎夷,調用 class_addIvar 函數(shù)。但是得在調用 objc_allocateClassPair 之后昧旨,objc_registerClassPair 之前拾给,原因同上。

UITableview的優(yōu)化方法

緩存高度兔沃,異步繪制蒋得,減少層級,hide乒疏,減少空間额衙,估算高度,避免離屏渲染怕吴。

有沒有用過運行時窍侧,用它都能做什么?

交換方法转绷,創(chuàng)建類伟件,給新創(chuàng)建的類增加方法,改變isa指針

5议经、AFN為什么添加一條常駐線程斧账?

http://www.reibang.com/p/e59bb8f59302

KVO的使用谴返?實現(xiàn)原理?(為什么要創(chuàng)建子類來實現(xiàn))

?? ? 當觀察某對象 A 時其骄,KVO 機制動態(tài)創(chuàng)建一個對象A當前類的子類亏镰,并為這個新的子類重寫了被觀察屬性 keyPath setter 方法。setter 方法隨后負責通知觀察對象屬性的改變狀況拯爽。

深入剖析:

?? ? Apple使用了 isa 混寫(isa-swizzling)來實現(xiàn) KVO 索抓。當觀察對象A時,KVO機制動態(tài)創(chuàng)建一個新的名為:NSKVONotifying_A 的新類毯炮,該類繼承自對象A的本類逼肯,且 KVO 為 NSKVONotifying_A 重寫觀察屬性的 setter 方法,setter 方法會負責在調用原 setter 方法之前和之后桃煎,通知所有觀察對象屬性值的更改情況篮幢。

(備注: isa 混寫(isa-swizzling)isa:is a kind of ; swizzling:混合为迈,攪合三椿;)

?? ? ①NSKVONotifying_A 類剖析:在這個過程,被觀察對象的 isa 指針從指向原來的 A 類葫辐,被 KVO 機制修改為指向系統(tǒng)新創(chuàng)建的子類 NSKVONotifying_A 類搜锰,來實現(xiàn)當前類屬性值改變的監(jiān)聽;

所以當我們從應用層面上看來耿战,完全沒有意識到有新的類出現(xiàn)蛋叼,這是系統(tǒng)“隱瞞”了對 KVO 的底層實現(xiàn)過程,讓我們誤以為還是原來的類剂陡。但是此時如果我們創(chuàng)建一個新的名為“NSKVONotifying_A”的類()狈涮,就會發(fā)現(xiàn)系統(tǒng)運行到注冊 KVO 的那段代碼時程序就崩潰,因為系統(tǒng)在注冊監(jiān)聽的時候動態(tài)創(chuàng)建了名為 NSKVONotifying_A 的中間類鸭栖,并指向這個中間類了歌馍。

(isa 指針的作用:每個對象都有 isa 指針,指向該對象的類晕鹊,它告訴 Runtime 系統(tǒng)這個對象的類是什么松却。所以對象注冊為觀察者時,isa 指針指向新子類捏题,那么這個被觀察的對象就神奇地變成新子類的對象(或實例)了玻褪。) 因而在該對象上對 setter 的調用就會調用已重寫的 setter肉渴,從而激活鍵值通知機制公荧。

—>我猜,這也是 KVO 回調機制同规,為什么都俗稱KVO技術為黑魔法的原因之一吧:內部神秘循狰、外觀簡潔窟社。

? ? ? ②子類setter方法剖析:KVO 的鍵值觀察通知依賴于 NSObject 的兩個方法:willChangeValueForKey:和 didChangevlueForKey:,在存取數(shù)值的前后分別調用 2 個方法:

被觀察屬性發(fā)生改變之前绪钥,willChangeValueForKey:被調用灿里,通知系統(tǒng)該 keyPath 的屬性值即將變更;當改變發(fā)生后程腹, didChangeValueForKey: 被調用匣吊,通知系統(tǒng)該 keyPath 的屬性值已經(jīng)變更;之后寸潦, observeValueForKey:ofObject:change:context: 也會被調用色鸳。且重寫觀察屬性的 setter 方法這種繼承方式的注入是在運行時而不是編譯時實現(xiàn)的。

? ? KVO為子類的觀察者屬性重寫調用存取方法的工作原理在代碼中相當于:

-(void)setName:(NSString *)newName{?

[self willChangeValueForKey:@"name"];? ? //KVO在調用存取方法之前總調用?

[super setValue:newName forKey:@"name"]; //調用父類的存取方法?

[self didChangeValueForKey:@"name"];? ? //KVO在調用存取方法之后總調用

}

KVC的使用见转?實現(xiàn)原理命雀?(KVC拿到key以后,是如何賦值的斩箫?知不知道集合操作符吏砂,能不能訪問私有屬性,能不能直接訪問_ivar

kvc最常見的兩種用法就是:1乘客,對私有變量進行賦值? 2狐血,字典轉模型

http://blog.csdn.net/coyote1994/article/details/52454600

http://hl1987.com/2015/12/16/理解Objective-C中的消息發(fā)送/

objective—c消息轉發(fā)機制

objc_msgSend的具體流程如下:

?1、通過isa指針找到所屬類

?2寨典、查找類的cache列表, 如果沒有則下一步

?3氛雪、查找類的”方法列表”

?4、如果能找到與選擇子名稱相符的方法, 就跳至其實現(xiàn)代碼

?5耸成、找不到, 就沿著繼承體系繼續(xù)向上查找

?6报亩、如果能找到與選擇子名稱相符的方法, 就跳至其實現(xiàn)代碼

?7、找不到, 執(zhí)行”消息轉發(fā)”.

消息轉發(fā)

上面我們提到, 如果到最后都找不到, 就會來到消息轉發(fā)井氢,消息轉發(fā)的流程如下:

1弦追、動態(tài)方法解析 : 先問接收者所屬的類, 你看能不能動態(tài)添加個方法來處理這個”未知的消息”? 如果能, 則消息轉發(fā)結束.

2、備胎(后備接收者) : 請接收者看看有沒有其他對象能處理這條消息? 如果有, 則把消息轉給那個對象, 消息轉發(fā)結束.

3花竞、消息簽名 : 這里會要求你返回一個消息簽名, 如果返回nil, 則消息轉發(fā)結束.

4劲件、完整的消息轉發(fā) : 備胎都搞不定了, 那就只能把該消息相關的所有細節(jié)都封裝到一個NSInvocation對象, 再問接收者一次, 快想辦法把這個搞定了. 到了這個地步如果還無法處理, 消息轉發(fā)機制也無能為力了。

OC中給空對象發(fā)送消息程序會Crash嗎约急?

? ? 首先零远,OC中向nil發(fā)消息,程序是不會崩潰的厌蔽。

? ? 因為OC的函數(shù)調用都是通過objc_msgSend進行消息發(fā)送來實現(xiàn)的牵辣,相對于C和C++來說,對于空指針的操作會引起Crash的問題奴饮,而objc_msgSend會通過判斷self來決定是否發(fā)送消息纬向,如果selfnil择浊,那么selector也會為空,直接返回逾条,所以不會出現(xiàn)問題琢岩。視方法返回值,向nil發(fā)消息可能會返回nil(返回值為對象)师脂、0(返回值為一些基礎數(shù)據(jù)類型)或0X0(返回值為id)等担孔。但是對[NSNull null]對象發(fā)送消息時,是會crash的吃警,因為這個NSNull類只有一個null方法攒磨。

? ? 當然,如果一個對象已經(jīng)被釋放了(引用計數(shù)為0了)汤徽,那么這個時候再去調用方法肯定是會Crash的娩缰,因為這個時候這個對象就是一個野指針(指向僵尸對象(對象的引用計數(shù)為0,指針指向的內存已經(jīng)不可用)的指針)了谒府,安全的做法是釋放后將對象重新置為nil拼坎,使它成為一個空指針,大家可以在關閉ARC后手動release對象驗證一下完疫。

iOS數(shù)據(jù)加密方式

md5加密泰鸡、aes加密、base64加密

delegate壳鹤、notification盛龄、KVO各優(yōu)缺點

delegate?的?優(yōu)勢?:

????? 1.非常嚴格的語法。所有將聽到的事件必須是在delegate協(xié)議中有清晰的定義芳誓。

????? 2.如果delegate中的一個方法沒有實現(xiàn)那么就會出現(xiàn)編譯警告/錯誤

????? 3.協(xié)議必須在controller的作用域范圍內定義

? ? ? 4.在一個應用中的控制流程是可跟蹤的并且是可識別的余舶;

????? 5.在一個控制器中可以定義定義多個不同的協(xié)議,每個協(xié)議有不同的delegates

????? 6.沒有第三方對象要求保持/監(jiān)視通信過程锹淌。

????? 7.能夠接收調用的協(xié)議方法的返回值匿值。這意味著delegate能夠提供反饋信息給controller

??????缺點?

????? 1.需要定義很多代碼:1.協(xié)議定義;2.controller的delegate屬性赂摆;3.在delegate本身中實現(xiàn)delegate方法定義

????? 2.在釋放代理對象時挟憔,需要小心的將delegate改為nil。一旦設定失敗烟号,那么調用釋放對象的方法將會出現(xiàn)內存crash

????? 3.在一個controller中有多個delegate對象绊谭,并且delegate是遵守同一個協(xié)議,但還是很難告訴多個對象同一個事件汪拥,不過有可能达传。

notification?的?優(yōu)勢?:

????? ? 1.不需要編寫多少代碼,實現(xiàn)比較簡單;

??????? 2.對于一個發(fā)出的通知趟大,多個對象能夠做出反應,即1對多的方式實現(xiàn)簡單

??????? 3.controller能夠傳遞context對象(dictionary)铣焊,context對象攜帶了關于發(fā)送通知的自定義的信息

????????缺點?:

??????? 1.在編譯期不會檢查通知是否能夠被觀察者正確的處理逊朽;?

??????? 2.在釋放注冊的對象時,需要在通知中心取消注冊曲伊;

??????? 3.在調試的時候應用的工作以及控制過程難跟蹤叽讳;

??????? 4.需要第三方對喜愛那個來管理controller與觀察者對象之間的聯(lián)系;

??????? 5.controller和觀察者需要提前知道通知名稱坟募、UserInfo dictionary keys岛蚤。如果這些沒有在工作區(qū)間定義,那么會出現(xiàn)不同步的情況懈糯;

??????? 6.通知發(fā)出后涤妒,controller不能從觀察者獲得任何的反饋信息。

KVO?的?優(yōu)勢?:

???????? 1.能夠提供一種簡單的方法實現(xiàn)兩個對象間的同步赚哗。例如:model和view之間同步她紫;

???????? 2.能夠對非我們創(chuàng)建的對象,即內部對象的狀態(tài)改變作出響應屿储,而且不需要改變內部對象(SKD對象)的實現(xiàn)贿讹;

???????? 3.能夠提供觀察的屬性的最新值以及先前值;

???????? 4.用key paths來觀察屬性够掠,因此也可以觀察嵌套對象民褂;

???????? 5.完成了對觀察對象的抽象,因為不需要額外的代碼來允許觀察值能夠被觀察

????????缺點?:

???????? 1.我們觀察的屬性必須使用strings來定義疯潭。因此在編譯器不會出現(xiàn)警告以及檢查赊堪;

???????? 2.對屬性重構將導致我們的觀察代碼不再可用;

???????? 3.復雜的“IF”語句要求對象正在觀察多個值竖哩。這是因為所有的觀察代碼通過一個方法來指向雹食;

???????? 4.當釋放觀察者時不需要移除觀察者。

1.??效率?肯定是delegate比NSNotification高期丰。

delegate方法比notification更加直接群叶,最典型的特征是,delegate方法往往需要關注返回值钝荡, 也就是delegate方法的結果街立。比如-windowShouldClose:,需要關心返回的是yes還是no埠通。所以delegate方法往往包含 should這個很傳神的詞赎离。也就是好比你做我的delegate,我會問你我想關閉窗口你愿意嗎端辱?你需要給我一個答案梁剔,我根據(jù)你的答案來決定如何做下一 步虽画。相反的,notification最大的特色就是不關心接受者的態(tài)度荣病, 我只管把通告放出來码撰,你接受不接受就是你的事情,同時我也不關心結果个盆。所以notification往往用did這個詞匯脖岛,比如 NSWindowDidResizeNotification,那么NSWindow對象放出這個notification后就什么都不管了也不會等待接受者的反應颊亮。

2柴梆、KVO和NSNotification的區(qū)別?:

和delegate一樣,KVO和NSNotification的作用也是類與類之間的通信终惑,與delegate不同的是1)這兩個都是負責發(fā)出通知绍在,剩下的事情就不管了,所以沒有返回值雹有;2)delegate只是一對一揣苏,而這兩個可以一對多。這兩者也有各自的特點件舵。

NSUrlSessionNSURLConnection區(qū)別

http://www.reibang.com/p/5c09d6976d8b

為什么棄用NSURLConnection?

1卸察、NSUrlSession不用每次都新建tcp鏈接。2铅祸、NSUrlSession速度更快坑质。3NSUrlSession更加安全临梗。

http://www.reibang.com/p/079e5cf0f014

UIView CALayer 的關系如何涡扼?他們分別負責什么功能?為什么這樣設計盟庞?

1.首先UIView可以響應事件吃沪,Layer不可以.

2.一個 Layer frame 是由它的 anchorPoint,position,bounds, transform 共同決定的,而一個 View frame 只是簡單的返回 Layer frame什猖,同樣 View center bounds 也是返回 Layer 的一些屬性砰盐。

3.UIView主要是對顯示內容的管理而 CALayer 主要側重顯示內容的繪制辞嗡。

4.在做 iOS 動畫的時候队贱,修改非 RootLayer的屬性(譬如位置兔朦、背景色等)會默認產(chǎn)生隱式動畫,而修改UIView則不會摇零。

view負責了與人的動作交互以及對layer的管理推掸,layer則負責了所有能讓人看到的東西。

uiview super class:UIResponder

calayer? super class:NSObject

uiresponder? super class:NSObject

http://www.cnblogs.com/flyFreeZn/p/4264220.html

ARC內存管理技術要點

http://www.reibang.com/p/17e158a666b1

http://www.reibang.com/p/927c8384855a

runtime機制

?? ? 我們寫的代碼在程序運行過程中都會被轉化成runtime的C代碼執(zhí)行,例如[target doSomething];會被轉化成objc_msgSend(target, @selector(doSomething));谅畅。

?? ? OC中一切都被設計成了對象登渣,我們都知道一個類被初始化成一個實例,這個實例是一個對象毡泻。實際上一個類本質上也是一個對象胜茧,在runtime中用結構體表示。

//類在runtime中的表示

struct objc_class {

? ? Class isa;//指針牙捉,顧名思義,表示是一個什么敬飒,

? ? //實例的isa指向類對象邪铲,類對象的isa指向元類

#if !__OBJC2__

? ? Class super_class;? //指向父類

? ? const char *name;? //類名

? ? long version;

? ? long info;

? ? long instance_size

? ? struct objc_ivar_list *ivars //成員變量列表

? ? struct objc_method_list **methodLists; //方法列表

? ? struct objc_cache *cache;//緩存

? ? //一種優(yōu)化,調用過的方法存入緩存列表无拗,下次調用先找緩存

? ? struct objc_protocol_list *protocols //協(xié)議列表

? ? #endif

} OBJC2_UNAVAILABLE;

http://www.reibang.com/p/a6b675f4d073

方法交換

OC中每個方法的名字(SEL)跟函數(shù)的實現(xiàn)(IMP)是一一對應带到,Swizzle的原理只是在這個地方做下手腳,將原來方法名與實現(xiàn)的指向交叉處理英染,就能達到一個新的效果揽惹。

靜態(tài)庫和動態(tài)庫

framework為什么既是靜態(tài)庫又是動態(tài)庫?

答:系統(tǒng)的.framework是動態(tài)庫四康,我們自己建立的.framework是靜態(tài)庫搪搏。

a與.framework有什么區(qū)別?

答:.a是一個純二進制文件闪金,.framework中除了有二進制文件之外還有資源文件疯溺。

.a文件不能直接使用,至少要有.h文件配合哎垦,.framework文件可以直接使用囱嫩。

.a + .h + sourceFile = .framework。

建議用.framework.

FMDB

?? ? 在多個線程中同時使用一個FMDatabase實例是不明智的漏设。不要讓多個線程分享同一個FMDatabase實例墨闲,它無法在多個線程中同時使用。 如果在多個線程中同時使用一個FMDatabase實例郑口,會造成數(shù)據(jù)混亂等問題鸳碧。所以,請使用 FMDatabaseQueue犬性,它是線程安全的

UIView生命周期

loadView方法

?? loadView方法在UIViewController對象的view屬性被訪問到且為空的時候調用杆兵。這個方法不應該被直接調用,而是由系統(tǒng)自動調用仔夺。它會加載或創(chuàng)建一個view并把它賦值給UIViewController的view屬性琐脏。

viewDidLoad方法

@synthesize @dynamic 分別有什么作用?

1 @property有兩個對應的詞,一個是 @synthesize日裙,一個是 @dynamic吹艇。如果 @synthesize 和 @dynamic 都沒寫,那么默認的就是 @syntheszie var = _var;

2 @synthesize的語義是如果你沒有手動實現(xiàn) setter 方法和 getter 方法昂拂,那么編譯器會自動為你加上這兩個方法受神。

3 @dynamic告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現(xiàn),不自動生成格侯。(當然對于 readonly 的屬性只需提供 getter 即可)鼻听。假如一個屬性被聲明為 @dynamic var,然后你沒有提供 @setter 方法和 @getter 方法联四,編譯的時候沒問題撑碴,但是當程序運行到 instance.var = someVar,由于缺 setter 方法會導致程序崩潰朝墩;或者當運行到 someVar = var 時醉拓,由于缺 getter 方法同樣會導致崩潰。編譯時沒問題收苏,運行時才執(zhí)行相應的方法亿卤,這就是所謂的動態(tài)綁定。

objc中的類方法和實例方法有什么本質區(qū)別和聯(lián)系

類方法:

1鹿霸,類方法是屬于類對象的 2排吴,類方法只能通過類對象調用 3,類方法中的self是類對象 4,類方法中不能訪問成員變量 5懦鼠,類方法可以調用其他的類方法 6傍念,類方法中不能直接調用對象方法

實例方法:

1,實例方法是屬于實例對象的 2葛闷,實例方法只能通過實例對象調用憋槐,3,實例方法中的self是實例對象 4淑趾,實例方法中可以訪問成員變量 5阳仔,實例方法中直接調用實例方法6,實例方法中可以直接調用類方法(通過類名)

runtime如何通過selector找到對應的IMP地址扣泊?

答:selector是通過方法名去查找近范,而在oc中,類因為runtime會被轉化成結構體延蟹,結構體里的成員變量? structobjc_method_list **methodLists? 里面存儲的是類方法列表和實例方法列表评矩,所以在runtime中,selector是通過找方法列表去找到對應的imp地址阱飘。

struct objc_method_list **methodLists 存儲的內容:http://blog.csdn.net/nynllwp/article/details/49926619

1.首先到該類的方法cache中去尋找斥杜,如果找到了虱颗,返回改函數(shù)

2.如果沒有找到就到該類的方法列表中查找,如果找到了蔗喂,將該IMP返回并且將它加入到cache中緩存起來忘渔,這樣可以節(jié)省再次調用的開銷。

3.如果還沒有找到缰儿,通過該類結構中的super_class指針去它的弗雷的方法列表中尋找畦粮,如果找到了了對應的IMP,返回IMP并加入cache

4.如果在自身及父類的方法列表中都沒有找到,則看是否可以動態(tài)決議(本文先不講)

5.如果動態(tài)方法決議沒有解決乖阵,進入消息轉發(fā)流程(本文先不講)

SEL是否只和方法名有關

答:相同名字的SEL指向同一塊內存地址宣赔,不通的類可以擁有相同的SEL, 根據(jù)同一個SEL找到的對應的IMP是不同的。

直接調用函數(shù)會節(jié)省方法調用時消息傳遞的開銷瞪浸,那么直接調用函數(shù)是否比oc本身的消息傳遞效率更高儒将?

答:在調用次數(shù)少于10000次時,直接調用函數(shù)指針的效率優(yōu)勢并不明顯默终,有時候還是oc的消息傳遞效率更好椅棺,只有循環(huán)次數(shù)非常大的時候犁罩,直接調用函數(shù)指針才有效率優(yōu)勢齐蔽。

http://www.reibang.com/p/700f58eb0b86

copy,MutableCopy的區(qū)別

淺復制:不拷貝對象本身,僅僅是拷貝指向對象的指針床估,一般來說像這種使用’=’號賦值的對象含滴,基本上都是淺復制。

深復制:是直接拷貝整個對象內存到另一塊內存中

? ? copy的字面意思就是“復制”丐巫,它是產(chǎn)生一個副本的過程谈况,再來看在iOS里,copy與mutableCopy都是NSObject里的方法递胧,一個NSObject的對象要想使用這兩個函數(shù)碑韵,那么類必須實現(xiàn)NSCopying協(xié)議或NSMutableCopying協(xié)議,并且是實現(xiàn)了一般來說我們用的很多系統(tǒng)里的容器類已經(jīng)實現(xiàn)了這些方法缎脾。

copy到底是深拷貝還是淺拷貝祝闻?

答:我相信有的同學認為只要是使用copy關鍵字,那么肯定都是深拷貝遗菠,這樣是很不嚴謹?shù)牧捅热缟蟼€例子,雖然使用了copy辙纬,但是指針地址是一樣豁遭,那么它就應該是淺拷貝。

所以是否是深淺拷貝贺拣,是否創(chuàng)建新的對象蓖谢,是由程序運行的環(huán)境所造成的捂蕴,并不是一概而論。

NSString為什么用的copy

?? ? 假如有一個NSMutableString,現(xiàn)在用他給一個retain修飾 NSString賦值,那么只是將NSString指向了NSMutableString所指向的位置,并對NSMUtbaleString計數(shù)器加一,此時,如果對NSMutableString進行修改,也會導致NSString的值修改,原則上這是不允許的. 如果是copy修飾的NSString對象,在用NSMutableString給他賦值時,會進行深拷貝,及把內容也給拷貝了一份,兩者指向不同的位置,即使改變了NSMutableString的值,NSString的值也不會改變.

? ? 所以用copy是為了安全,防止NSMutableString賦值給NSString時,前者修改引起后者值變化而用的.

高效圓角

第一種:設置CALayer的cornerRadius

?imageView.image = [UIImage imageNamed:@"img"];

?imageView.image.layer.cornerRadius = 5;

?imageView.image.layer.masksToBounds =YES;

這樣設置會觸發(fā)離屏渲染蜈抓,比較消耗性能启绰。比如當一個頁面上有十幾頭像這樣設置了圓角

會明顯感覺到卡頓。

這種就是最常用的沟使,也是最耗性能的委可。

注意:ios9.0之后對UIImageView的圓角設置做了優(yōu)化,UIImageView這樣設置圓角

不會觸發(fā)離屏渲染腊嗡,ios9.0之前還是會觸發(fā)離屏渲染着倾。而UIButton還是都會觸發(fā)離屏渲染。

第二種

imageView.clipsToBounds = YES;

imageView.layer setCornerRadius:50];

imageView.layer.shouldRasterize = YES;

shouldRasterize=YES設置光柵化燕少,可以使離屏渲染的結果緩存到內存中存為位圖卡者, 使用的時候直接使用緩存,節(jié)省了一直離屏渲染損耗的性能客们。

但是如果layer及sublayers常常改變的話崇决,它就會一直不停的渲染及刪除緩存重新 創(chuàng)建緩存,所以這種情況下建議不要使用光柵化底挫,這樣也是比較損耗性能的恒傻。

第三種 :通過Core Graphics重新繪制帶圓角的視圖

這種方式性能最好,但是UIButton上不知道怎么繪制建邓,可以用UIimageView添加個 點擊手勢當做UIButton使用

@implementation UIImage (CircleImage)

- (UIImage *)drawCircleImage {

?? UIGraphicsBeginImageContextWithOptions(self.bounds.size,NO, [UIScreen mainScreen].scale);?

?? [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:50] addClip];?

?? [self drawInRect:self.bounds];?

?? UIImage *output = UIGraphicsGetImageFromCurrentImageContext();

?? UIGraphicsEndImageContext();

?? return output;?

}

?@end

//在需要圓角時調用如下

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

? ? UIImage *img = [[UIImage imageNamed:@"image.png"] drawCircleImage];

? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? imageView.image = img;

? ? });

});

四盈厘、通過混合圖層

此方法就是在要添加圓角的視圖上再疊加一個部分透明的視圖,只對圓角部分進行遮擋官边。圖層混合的透明度處理方式與mask正好相反沸手。此方法雖然是最優(yōu)解,沒有離屏渲染注簿,沒有額外的CPU計算契吉,但是應用范圍有限。

總結

1 在可以使用混合圖層遮擋的場景下诡渴,優(yōu)先使用第四種方法捐晶。

2 即使是非iOS9以上系統(tǒng),第一種方法在綜合性能上依然強于后兩者玩徊,iOS9以上由于沒有了離屏渲染更是首選租悄。

3 方法三由于需要大量計算和增加部分內存,需要實際情況各自取舍恩袱。

http://www.cocoachina.com/ios/20170502/19163.html

CategoryExtension

Category:

? category只能給某個已有的類擴充方法泣棋,不能擴充成員變量。

? category中也可以添加屬性畔塔,只不過@property只會生成setter和getter的聲明潭辈,不會生成setter和getter的實現(xiàn)以及成員變量鸯屿。

? 如果category中的方法和類中原有方法同名,運行時會優(yōu)先調用category中的方法把敢。也就是寄摆,category中的方法會覆蓋掉類中原有的方法。所以開發(fā)中盡量保證不要讓分類中的方法和原有類中的方法名相同修赞。避免出現(xiàn)這種情況的解決方案是給分類的方法名統(tǒng)一添加前綴婶恼。比如category_。

? 如果多個category中存在同名的方法柏副,運行時到底調用哪個方法由編譯器決定勾邦,最后一個參與編譯的方法會被調用。

調用優(yōu)先級

分類(category) > 本類 > 父類割择。即眷篇,優(yōu)先調用cateory中的方法,然后調用本類方法荔泳,最后調用父類方法蕉饼。 注意:category是在運行時加載的,不是在編譯時玛歌。

Category與屬性和變量:

? ? 在類中昧港,聲明一個屬性,編譯器會自動幫我們生成帶下劃線的成員變量和_ivar以及setter/getter方法沾鳄,ivar會添加到類轉化的結構體的成員變量struct?objc_ivar_list?*ivars里面慨飘,而setter/getter方法則會放到struct?objc_method_list?**methodLists里面确憨。

? ? 由于category是在運行時加載的译荞,不是在編譯時,并且在Runtime中休弃,類會轉化成結構體來表示吞歼,所以轉化的objc_class結構體大小在runtime時期就已經(jīng)是固定的了,已經(jīng)編譯好了塔猾,那么就不可能往這個結構體中添加數(shù)據(jù)篙骡,只能修改。

?? 所謂的可以在Category里面可以添加成員變量僅僅是關聯(lián)了另外一個屬性丈甸,這些東西和之前的類并不在一個內存空間糯俗。

extension:

? ? extension在編譯期決議,它就是類的一部分睦擂。extension在編譯期和頭文件里的@interface以及實現(xiàn)文件里的@implement一起形成一個完整的類得湘,它、extension伴隨類的產(chǎn)生而產(chǎn)生顿仇,亦隨之一起消亡淘正。

? ? extension一般用來隱藏類的私有信息摆马,你必須有一個類的源碼才能為一個類添加extension,所以你無法為系統(tǒng)的類比如NSString添加extension鸿吆,除非創(chuàng)建子類再添加extension囤采。而category不需要有類的源碼,我們可以給系統(tǒng)提供的類添加category惩淳。

? ? extension可以添加實例變量蕉毯,而category不可以。

? ? extension和category都可以添加屬性思犁,但是category的屬性不能生成成員變量和getter恕刘、setter方法的實現(xiàn)。

NSNotification

NSNotification在發(fā)送通知的時候抒倚,是同步褐着。可以使用gcd改成異步托呕。在不使用的時候記住要移除通知含蓉。

iOS消息推送

1、應用程序注冊消息推送项郊。

2馅扣、iOS從APNS Server獲取device token,應用程序接收device token着降。

3差油、應用程序將device token發(fā)送給PUSH服務端程序。

4任洞、服務端程序向APNS服務發(fā)送消息蓄喇。

5、APNS服務將消息發(fā)送給iPhone應用程序交掏。

http://www.reibang.com/p/4db013fa8c02

hook(不是很懂)

不進行在結構體里查找方法的過程妆偏,直接進入到消息轉發(fā)的第一個過程。

在Objective-C中調用一個方法盅弛,其實是向一個對象發(fā)送消息钱骂,查找消息的唯一依據(jù)是selector的名字。利用Objective-C的動態(tài)特性挪鹏,可以實現(xiàn)在運行時偷換selector對應的方法實現(xiàn)见秽,達到給方法掛鉤的目的。

大體分兩步:

1讨盒、直接替換原方法的實現(xiàn)為_objc_msgForward解取。當原來的函數(shù)被調用時,就不會在類方法催植,父類方法列表里查找實現(xiàn)了肮蛹,直接表示找不到勺择,進入轉發(fā)流程。代碼如下:

class_replaceMethod(class, selector, _objc_msgForward, method_getTypeEncoding(targetMethod));

用_objc_msgForward來代替原來的函數(shù)伦忠。

2省核、替換forwardInvocation:的實現(xiàn),當進入轉發(fā)流程時昆码,階段一和階段二都不接手气忠,在階段三forwardInvocation:里會接手。

屏幕渲染

OpenGL中,GPU屏幕渲染有兩種方式.

On-Screen Rendering (當前屏幕渲染)

指的是GPU的渲染操作是在當前用于顯示的屏幕緩沖區(qū)進行.

Off-Screen Rendering (離屏渲染)

指的是在GPU在當前屏幕緩沖區(qū)以外開辟一個緩沖區(qū)進行渲染操作.

特殊的離屏渲染:

如果將不在GPU的當前屏幕緩沖區(qū)中進行的渲染都稱為離屏渲染赋咽,那么就還有另一種特殊的“離屏渲染”方式: CPU渲染旧噪。

如果我們重寫了drawRect方法,并且使用任何Core Graphics的技術進行了繪制操作脓匿,就涉及到了CPU渲染淘钟。整個渲染過程由CPU在App內 同步地完成,渲染得到的bitmap最后再交由GPU用于顯示陪毡。

備注:CoreGraphic通常是線程安全的米母,所以可以進行異步繪制,顯示的時候再放回主線程毡琉,一個簡單的異步繪制過程大致如下

Off-Screen Rendering (離屏渲染)

? ? 離屏渲染的代價很高,想要進行離屏渲染,首選要創(chuàng)建一個新的緩沖區(qū),屏幕渲染會有一個上下文環(huán)境的一個概念,離屏渲染的整個過程需要切換上下文環(huán)境,先從 當前屏幕切換到離屏,等結束后,又要將上下文環(huán)境切換回來.這也是為什么會消耗性能的原因了(有個屏幕和離屏切換的過程)铁瞒。由于垂直同步的機制,如果在一個 HSync(水平同步信號) 時間內桅滋,CPU 或者 GPU 沒有完成內容提交慧耍,則那一幀就會被丟棄,等待下一次機會再顯示丐谋,而這時顯示屏會保留之前的內容不變芍碧。這就是界面卡頓的原因。

?? 當使用圓角笋鄙,陰影师枣,遮罩的時候怪瓶,圖層屬性的混合體被指定為在未預合成之前(下一個HSync信號開始前)不能直接在屏幕中繪制萧落,所以就需要屏幕外渲染。 你可以這么理解. 老板叫我短時間間內做一個 app.我一個人能做,但是時間太短,所以我得讓我朋友一起來幫著我做.(性能消耗: 也就是耗 你跟你朋友之間溝通的這些成本,多浪費啊).但是沒辦法 誰讓你做不完呢.

上下文切換

? ? 上下文切換洗贰,不管是在GPU渲染過程中找岖,還是一直所熟悉的進程切換,上下文切換在哪里都是一個相當耗時的操作敛滋。首先我要保存當前屏幕渲染環(huán)境许布,然后切換到一個新的繪制環(huán)境,申請繪制資源绎晃,初始化環(huán)境蜜唾,然后開始一個繪制杂曲,繪制完畢后銷毀這個繪制環(huán)境,如需要切換到On-Screen

Rendering或者再開始一個新的離屏渲染重復之前的操作袁余。

會離屏渲染的操作

shouldRasterize(光柵化)擎勘、masks(遮罩)、shadows(陰影)颖榜、edge antialiasing(抗鋸齒)棚饵、group opacity(不透明)、復雜形狀設置圓角等掩完、漸變噪漾、Text(UILabel, CATextLayer, Core Text, etc)等

如何檢測我的項目里面離屏渲染?

?*之前看了一些文章說在intruments里面的 CoreAnimation里面有工具.檢測.(沒找著.求補充)

iOS版本上的優(yōu)化

?? iOS 9.0之前UIimageView跟UIButton設置圓角都會觸發(fā)離屏渲染

?? iOS 9.0之后UIButton設置圓角會觸發(fā)離屏渲染且蓬,而UIImageView里png圖片設置圓角不會觸發(fā)離屏渲染了欣硼,如果設置其他陰影效果之類的還是會觸發(fā)離屏渲染的。

?? UIButton設置圓角不觸發(fā)離屏渲染可以使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角恶阴。

? ? 這可能是蘋果也意識到離屏渲染會產(chǎn)生性能問題分别,所以能不產(chǎn)生離屏渲染的地方蘋果也就不用離屏渲染了。

http://blog.csdn.net/hopedark/article/details/49640939

@synchronized

@synchronized(obj) {

? ? // do work

}

轉化成這樣的東東

@try {

? ? objc_sync_enter(obj);

? ? // do work

} @finally {

? ? objc_sync_exit(obj);? ?

}

objc_sync_enter 的文檔告訴我們一些新東西: @synchronized 結構在工作時為傳入的對象分配了一個遞歸鎖存淫。

方法和選擇器有何不同耘斩?

答:selector(選擇器)是方法的名字,通過它可以找到方法

? ? ? 方法是相對于對象來說的桅咆,包含名字和實現(xiàn)等括授。

layoutSubview

在以下情況下會被調用:

1、init初始化不會觸發(fā)layoutSubviews

???但是是用initWithFrame?進行初始化時岩饼,當rect的值不為CGRectZero時,也會觸發(fā)

2荚虚、addSubview會觸發(fā)layoutSubviews

3、設置view的Frame會觸發(fā)layoutSubviews籍茧,當然前提是frame的值設置前后發(fā)生了變化

4版述、滾動一個UIScrollView會觸發(fā)layoutSubviews

5、旋轉Screen會觸發(fā)父UIView上的layoutSubviews事件

6寞冯、改變一個UIView大小的時候也會觸發(fā)父UIView上的layoutSubviews事件

什么時候重寫layoutSubviews渴析?

1 自動布局無法滿足要求(例如要自定義一個按鈕,圖片在文字的右側)

2 不要直接調用調用這個方法吮龄,可以調用setNeedsLayout俭茧、layoutIfNeeded。

1漓帚、layoutSubviews

?? ? 在iOS5.1和之前的版本母债,此方法的缺省實現(xiàn)不會做任何事情(實現(xiàn)為空),iOS5.1之后(iOS6開始)的版本,此方法的缺省實現(xiàn)是使用你設置在此view上面的constraints(Autolayout)去決定subviews的position和size毡们。 UIView的子類如果需要對其subviews進行更精確的布局迅皇,則可以重寫此方法。只有在autoresizing和constraint-based behaviors of subviews不能提供我們想要的布局結果的時候衙熔,我們才應該重寫此方法喧半。可以在此方法中直接設置subviews的frame青责。 我們不應該直接調用此方法挺据,而應當用下面兩個方法。

2脖隶、setNeedsLayout (設置成需要布局)

? ? 標記為需要重新布局扁耐,異步調用layoutIfNeeded刷新布局,不立即刷新产阱,在下一輪runloop結束前刷新婉称,對于這一輪runloop之內的所有布局和UI上的更新只會刷新一次,layoutSubviews一定會被調用构蹬。

3王暗、layoutIfNeeded

? ? 使用此方法強制立即進行l(wèi)ayout,從當前view開始,此方法會遍歷整個view層次(包括superviews)請求layout庄敛。因此俗壹,調用此方法會強制整個view層次布局。

關鍵點

layoutIfNeeded不一定會調用layoutSubviews方法藻烤。

setNeedsLayout一定會調用layoutSubviews方法(有延遲绷雏,在下一輪runloop結束前)。

如果想在當前runloop中立即刷新怖亭,調用順序應該是

[self setNeedsLayout];

[self layoutIfNeeded];

反之可能會出現(xiàn)布局錯誤的問題涎显。

http://www.reibang.com/p/915356e280fc

isEquelhash的關系

NSArrayNSMutableArray

往數(shù)組里加入nil是否會發(fā)生崩潰?

答:NSMutableArray會發(fā)生崩潰現(xiàn)象兴猩。無法往輸入里加入nil對象期吓。NSArray不會喷市,可以在初始化的時候把里面加入nil元素李命。

NSTimer

和block一樣拌喉,會對self進行引用哮兰,如果沒有按照流程釋放的話對造成循環(huán)引用而導致內存泄漏。它由于要對self進行引用饲齐,所以self將不會主動釋放缓窜,從而不會主動調用delloc函數(shù),所以問題就來了拯刁!如果在delloc里面釋放timer是不可取的,因為在沒有外部干涉的條件下它永遠不會調用delloc函數(shù)逝段,所以也就永遠不會釋放timer垛玻,造成內存泄漏割捅!



如果有侵犯到其他作者,請聯(lián)系我刪除帚桩!造成的不便亿驾,十分抱歉!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末账嚎,一起剝皮案震驚了整個濱河市莫瞬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郭蕉,老刑警劉巖疼邀,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異召锈,居然都是意外死亡旁振,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門涨岁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拐袜,“玉大人,你說我怎么就攤上這事梢薪〉牌蹋” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵秉撇,是天一觀的道長丛塌。 經(jīng)常有香客問我,道長畜疾,這世上最難降的妖魔是什么赴邻? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮啡捶,結果婚禮上姥敛,老公的妹妹穿的比我還像新娘。我一直安慰自己瞎暑,他們只是感情好彤敛,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著了赌,像睡著了一般墨榄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勿她,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天袄秩,我揣著相機與錄音,去河邊找鬼。 笑死之剧,一個胖子當著我的面吹牛郭卫,可吹牛的內容都是我干的。 我是一名探鬼主播背稼,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼贰军,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蟹肘?” 一聲冷哼從身側響起词疼,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎帘腹,沒想到半個月后贰盗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡竹椒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年童太,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胸完。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡书释,死狀恐怖,靈堂內的尸體忽然破棺而出赊窥,到底是詐尸還是另有隱情爆惧,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布锨能,位于F島的核電站扯再,受9級特大地震影響,放射性物質發(fā)生泄漏址遇。R本人自食惡果不足惜熄阻,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倔约。 院中可真熱鬧秃殉,春花似錦、人聲如沸浸剩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绢要。三九已至吏恭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間重罪,已是汗流浹背樱哼。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工哀九, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唇礁。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓勾栗,卻偏偏與公主長得像惨篱,于是被迫代替她去往敵國和親盏筐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容

  • 1.ios高性能編程 (1).內層 最小的內層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結構(3).初始化時...
    歐辰_OSR閱讀 29,320評論 8 265
  • 面試題參考1 : 面試題[http://www.cocoachina.com/ios/20150803/12872...
    江河_ios閱讀 1,706評論 0 4
  • OC語言基礎 1.類與對象 類方法 OC的類方法只有2種:靜態(tài)方法和實例方法兩種 在OC中砸讳,只要方法聲明在@int...
    奇異果好補閱讀 4,250評論 0 11
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,089評論 1 32
  • 興沖沖地注冊了簡書琢融,哈哈,終于有一個地方可以讓我盡情發(fā)泄我的小小的文字情節(jié)簿寂。興奮漾抬,興奮!
    行走的腳閱讀 238評論 0 0