NSLog(@"%@",[NSMutableArray arrayWithObject:@""].class); __NSArrayM框架
NSLog(@"%@",@[@"",@""].class); __NSArrayI指針
NSLog(@"%@",@[].class); __NSArray0code
當咱們建立一個NSArray對象時,實際上獲得的是NSArray的子類__NSArrayI
對象.一樣的,咱們建立NSMutableArray
對象,獲得的一樣是其子類__NSArrayM
對象.有趣的是,當咱們建立只有一個對象的NSArray
時,獲得的是__NSSingleObjectArrayI
類對象.__NSArrayI
和__NSArrayM
,__NSSingleObjectArrayI
爲框架隱藏的類.對象
經過NSArray和NSMutableArray接口,返回的倒是子類對象,怎麼作到的?
先介紹另外一個私有類:__NSPlaceholderArray
,和兩個此類的全局變量___immutablePlaceholderArray
,___mutablePlaceholderArray
。__NSPlaceholderArray
從類命名上看,它只是用來佔位的,具體怎麼佔位法稍後討論,有個重要特色是,__NSPlaceholderArray
實現了和NSArray
,NSMutableArray
一摸同樣的初始化方法,如initWithObjects:count:
,initWithCapacity:
等.接口
介紹完__NSPlaceholderArray
後,這個機制能夠總結爲如下兩個大步驟:
(1).NSArray重寫了+ (id)allocWithZone:(struct _NSZone *)zone
方法,在方法內部,若是調用類爲NSArray
則直接返回全局變量___immutablePlaceholderArray
,若是調用類爲NSMUtableArray
則直接返回全局變量___mutablePlaceholderArray
。
也就是調用[NSArray alloc]
或者[NSMUtableArray alloc]
獲得的僅僅是兩個佔位指針,類型爲__NSPlaceholderArray
.
(2).在調用了alloc
的基礎上,不管是NSArray
或NSMutableArray
都一定要繼續調用某個initXXX
方法,而實際上調用的是__NSPlaceholderArray
的initXXX
.在這個initXXX
方法內部,若是self == ___immutablePlaceholderArray
就會從新構造並返回__NSArrayI
對象,若是self == ___mutablePlaceholderArray
就會從新構造並返回_NSArrayM
對象.ci
總結來講,對於NSArray
和NSMutableArray
,alloc
時拿到的僅僅是個佔位對象,init
後才獲得真實的子類對象.it