轉載請註明出處: http://www.cnblogs.com/xdxer/p/4069650.htmlhtml
《Objective-C高級編程》 人民郵電出版社 是一本寫的很棒的書,日本做者對於細節摳的很仔細,深刻淺出,推薦學習Objective-C的同窗們購買。編程
#1 關於retainCount 變量在內存中是如何存放的?數組
在GNUStep(一種cocoa框架的互換框架)中retainCount和對象放置在一塊兒,在對象地址以前。因此有以下獲取GNUstep中retainCount的方式:緩存
-(NSUInteger) retainCount { return NSExtraRefCount(self) + 1; } inline NSUInteger NSExtraRefCount(id anObject) { return ((struct obj_layout *) anObject )[-1].retained; }
不過蘋果的實現是管理了一張hashTable,在經過hash(obj),在相應的位置加入該對象的引用技術retainCount和對象內存塊的地址。框架
雖然GNUstep的實現方式可能會更加直觀一些,不過蘋果這麼作也是有相應的好處的:函數
#2 autorelease & NSRunloop ?工具
NSAutoreleasePool這個類對於pool對象使用了管理者模式,即會管理許多個pool 而且記錄當前正在使用的pool,若是在別的地方使用了 [[[class alloc] init] autorelease],那麼該對象就會被加入這個正在使用的pool中。oop
#3 如何提升Objective-C方法的調用速度?性能
「IMP Caching」方法學習
提升頻繁調用的autorelease方法的速度:例
id autorelease_class = [NSAutoreleasePool class]; SEL autorelease_sel = @selector(addObject:); IMP autorelease_imp = [autorelease_class methodForSelector:autorelease_sel]; - (id) autorelease { (* autorelease_imp)(autorelease_class,autorelease_sel,self); } - (id)autorelease { [NSAutoreleasePool addObject:self]; }
在框架初始化的時候對,這幾個方法進行了緩存。第一種autorelease的調用速度是後者的2倍。由於Oc-runtime 中有對象之間發送消息的開銷。
#4 SEL 和 IMP的區別?
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...);
IMP 是一個函數指針,這個被指向的函數包含一個接收消息的對象id(self 指針), 調用方法的選標 SEL (方法名),以及不定個數的方法參數,並返回一個id。也就是說 IMP 是消息最終調用的執行代碼,是方法真正的實現代碼 。咱們能夠像在C語言裏面同樣使用這個函數指針。
#5 _weak 賦值給 _strong 時的狀況?
#6 _unsafe_unretained 爲什麼物?
實際上就是不會自動置nil的指針 (_weak),因此可能會出現野指針。
#7 @autorelease 塊
在塊結束的時候調用,[pool drain] ;
#8 C++智能指針的問題 std:: shared_ptr & std:: weak_ptr & std:: auto_ptr
引入了引用計數器的概念。
#9 NSZone是什麼?
在碰到allocWithZone, copyWithZone總會有個疑問,這個NSZone究竟是個什麼東西?簡單來講,能夠想象成一個內存池,alloc或是dealloc這些操做,都是在這個內存池中操做的。cocoa老是會配置一個默認的NSZone,任何默認的內存操做都是在這個「zone」上操做的。默認的NSZone的缺陷在於,它是全局範圍的,時間一長,必然會致使內存的碎片化,若是你須要大量的alloc一些object,那麼性能就會受到一些影響。全部cocoa提供方法,你能夠本身生成一個NSZone,並將alloc, copy所有限制在這個「zone」以內。
#10 在刪除動態數組的時候須要注意的?
須要講全部元素置爲nil,否則會發生內存泄漏。即便使用memset等函數將內存填充爲0也不會釋放所賦值的對象。對於編譯器,必須明確得使用賦值給附有_strong 修飾的變量的源代碼。
for( NSUInteger i = 0; i < entries ;++i ) array[i] = nil ; free(array);
#11 _weak表
在ARC條件下,當_weak指向的對象被釋放了,那麼_weak會自動被置爲nil,那麼runtime中是如何作到這一點的呢?
在內存中維護一張weak表。
/* oc代碼 */ { id __weak obj1 = obj; } /* 編譯器模擬代碼 */ id obj1; objc_initWeak(&obj1,obj); objc_destroyWeak(&obj1);
如上述代碼,key 爲對象的地址 obj ,values爲 _weak的地址&obj1 。 一個對象地址能夠對應不少個_weak變量地址,當一個對象被析構,那麼他在weak表中所指向的_weak變量就會被置爲nil。而後在weak表中刪除該記錄。
因爲使用_weak變量會形成以上的系統開銷,因此僅在須要避免循環引用的時候使用__weak修飾符。
#12 在ARC條件下如何獲取retainCount ?
使用: _objc_rootRetainCount(obj);