- 設(shè)計模式相關(guān):
設(shè)計模式是一種編碼經(jīng)驗, 就是以比較成熟的邏輯去處理某一類型的事情. 架構(gòu)模式: (1).MVC (2).MVVM (3)MVP (4)VIPER MV(X)系列詳解 英文原文->
iOS中常用設(shè)計模式: (1). 單例模式: 通過
static
關(guān)鍵字及dispatch_once
保證單列在程序運(yùn)行期間只會被初始化一次. (2). KVO: 通過runtime動態(tài)生成一個新的類, 并重寫被觀察對象屬性的setter
方法, 來監(jiān)聽對象屬性的改變 (3). 委托模式: protrcol + delegate (4).工廠模式: 通過一個類方法, 批量根據(jù)已有模板生產(chǎn)對象.
-
#import
和#incloud
的區(qū)別,@class
作用?
#import
和#incloud
都是用來導(dǎo)入頭文件.#incloud
是C/C++中用來導(dǎo)入頭文件的關(guān)鍵字;#import
是Objective-C中用來導(dǎo)入頭文件的關(guān)鍵字, 通過預(yù)編譯指令來防止文件多次導(dǎo)入;@class
用來告訴編譯器某個類的聲明, 到運(yùn)行時才去查看類的實(shí)現(xiàn)文件(.m
), 可以解決頭文件的相互包含.
-
frame
和bounds
的區(qū)別?
frame
是 自身在父view
坐標(biāo)系統(tǒng)中的位置和大小,bounds
是自身在自己的坐標(biāo)系統(tǒng)中的位置和大小
- Objective-C的類可以多重繼承么?Category是什么? Category重寫本類方法后,為什么本類方法不再執(zhí)行, 是被替換了嗎?
Objective-C
的類是不可以多繼承的.Category
分類, 其中的方法會在運(yùn)行時動態(tài)的添加到本類的method_list
中,Category
不能添加屬性, 原因是無法在運(yùn)行時本列的ivar_list
大小已經(jīng)確定, 無法動態(tài)的去添加_ivar
, 可以通過動態(tài)綁定objc_associated
來添加屬性. 因為在運(yùn)行時中, 本類的方法會先放入method_list
中去,Category
中添加的方法, 會進(jìn)行memory_copy
放入method_list
中, 排在本類方法的前邊, 如果和本類方法重名, 那么在調(diào)用的時候, 找到Category
中添加的方法后就會返回調(diào)用. 所以并不是被替換,而是根本就沒有調(diào)用到本類的方法去;
-
@property
的本質(zhì)是什么?
@property
本質(zhì)就是_ivar
冤议、setter
是趴、getter
. 屬性的本質(zhì)就是一個帶_
的實(shí)例變量 +setter``getter
存取方法. 一般們調(diào)用的時候盡量直接調(diào)用_ivar
, 這樣的好處是能夠直接對實(shí)例變量進(jìn)行賦值和讀取,不用再經(jīng)過存取方法
-
@property
有什么屬性關(guān)鍵字?都有什么作用?
(1): 原子性關(guān)鍵字:
atomic
-- 默認(rèn). 原子性, 當(dāng)屬性被atomic
修飾時,系統(tǒng)生成的setter
和getter
方法中, 會進(jìn)行加鎖操作, 這樣可以保證數(shù)據(jù)的完整性, 但并不能保證一定是線程安全的. 相較于nonatomic
而言, 內(nèi)存消耗更大.nonatomic
-- 非默認(rèn). 非原子性, 更快, 若多個線程同時訪問, 則結(jié)果無法預(yù)料.
(2)讀寫權(quán)限:readwrite
-- 默認(rèn). 可讀寫, 系統(tǒng)會自動生成setter
和getter
方法readonly
-- 非默認(rèn). 只可讀, 系統(tǒng)只會生成getter
方法, 不希望屬性在類外改變
(3)內(nèi)存管理語義:assign
:-- 賦值特性, 進(jìn)行簡單的賦值操作retain(MRC)/strong(ARC)
: -- 持有特性,setter
方法會將傳入的參數(shù)先保留, 再賦值. 傳入?yún)?shù)的retainCount
會+1copy
:-- 表示copy特性,setter
方法會將傳入?yún)?shù)復(fù)制一份, 常用于NSString, NSArray, NSDictionary
等, 不論傳入?yún)?shù)是否是可變對象, 自身持有的那一份保證不可變的屬性.weak
-- 表示一種非擁有關(guān)系
,weak
在屬性所指的對象被銷毀時, 屬性的值會被自動清空 weak底層實(shí)現(xiàn)
- 系統(tǒng)對象的
copy
呻纹、mutableCopy
和深拷貝、淺拷貝
- 非集合類對象的
copy
孝凌、mutableCopy
:
//!< 非集合類不可變對象:
NSString *str = @"hello word";
id copyStr = [str copy];
id mutableCopyStr = [str mutableCopy];
NSLog(@"str:%p class:%@ \n copyStr:%p class:%@ \n mutableCopyStr:%p class:%@", str, [str class], copyStr, [copyStr class], mutableCopyStr, [mutableCopyStr class]);
//!< 非集合類可變對象:
NSMutableString *str1 = [[NSMutableString alloc] initWithFormat:@"hello word"];
id copyStr1 = [str1 copy];
id mutableCopyStr1 = [str1 mutableCopy];
NSLog(@"str1:%p class:%@ \n copyStr1:%p class:%@ \n mutableCopyStr1:%p class:%@", str1, [str1 class], copyStr1, [copyStr1 class], mutableCopyStr1, [mutableCopyStr1 class]);
- 結(jié)果:
2019-04-23 16:57:57.185947+0800 JSOCInteraction[17107:6685981] str:0x102ef43b8 class:__NSCFConstantString
copyStr:0x102ef43b8 class:__NSCFConstantString
mutableCopyStr:0x6000001d2ac0 class:__NSCFString
2019-04-23 16:57:57.186221+0800 JSOCInteraction[17107:6685981] str1:0x6000001cbf00 class:__NSCFString
copyStr1:0x600000fc5660 class:__NSCFString
mutableCopyStr1:0x6000001cbdb0 class:__NSCFString
由上述代碼可以看出, 對非集合類不可變對象進(jìn)行copy
是淺拷貝
, 只復(fù)制了對象的指針, 而mutableCopy
是深拷貝
, 拷貝出了一份新的可變對象和一份指針; 對非集合類可變對象進(jìn)行copy
和mutableCopy
都是深拷貝
- 集合類對象的
copy
和mutableCopy
:
NSArray *arr = @[];
id copyArr = [arr copy];
id mutableCArr = [arr mutableCopy];
NSLog(@"arr:%p class:%@ \n \tcopyArr:%p class:%@ \n \tmutableCArr:%p class:%@", arr, [arr class], copyArr, [copyArr class], mutableCArr, [mutableCArr class]);
NSMutableArray *muArr = [NSMutableArray new];
id copyMuArr = [muArr copy];
id mutableCMuArr = [muArr mutableCopy];
NSLog(@"muArr:%p class:%@ \n \tcopyMuArr:%p class:%@ \n \tmutableCMuArr:%p class:%@", muArr, [muArr class], copyMuArr, [copyMuArr class], mutableCMuArr, [mutableCMuArr class]);
- 結(jié)果:
2019-04-23 16:57:57.186472+0800 JSOCInteraction[17107:6685981] arr:0x600000d88030 class:__NSArray0
copyArr:0x600000d88030 class:__NSArray0
mutableCArr:0x6000001cbf00 class:__NSArrayM
2019-04-23 16:57:57.187073+0800 JSOCInteraction[17107:6685981] muArr:0x6000001cbdb0 class:__NSArrayM
copyMuArr:0x600000d88030 class:__NSArray0
mutableCMuArr:0x6000001cbc00 class:__NSArrayM
由結(jié)果可見: 對不可變的集合類對象(NSArray, NSDictionary等
)進(jìn)行copy
是淺拷貝
; 進(jìn)行mutableCopy
是深拷貝
; 不過只是單層深拷貝
, 即只對對象本身進(jìn)行深拷貝
, 集合中的元素還是指針拷貝
; 對可變集合類對象進(jìn)行copy
和mutableCopy
都是進(jìn)行了單層深拷貝
.
- 如何讓自己的類用 copy 修飾符?
@interface WKCopyObject ()<NSCopying, NSMutableCopying>
@property (nonatomic, copy) NSString *name;
@end
- (id)copyWithZone:(NSZone *)zone {
WKCopyObject *obj = [[[self class] alloc] init];
obj.name = self.name;
return obj;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
WKCopyObject *obj = [[[self class] alloc] init];
obj.name = self.name.mutableCopy;
return obj;
}
-
autoreleasepool
的實(shí)現(xiàn)原理與釋放時機(jī)?
我們使用clang指令對
main.m
進(jìn)行rewrite
, 得到main.cpp
文件:clang -rewrite-objc main.m
, 可以看到有關(guān)autoreleasepool
的關(guān)鍵代碼:
extern "C" __declspec(dllimport) void * objc_autoreleasePoolPush(void);
extern "C" __declspec(dllimport) void objc_autoreleasePoolPop(void *);
struct __AtAutoreleasePool {
__AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
void * atautoreleasepoolobj;
};
可以看到
autoreleasepool
是一個由objc_autoreleasePoolPush()
、objc_autoreleasePoolPop()
和一個atautoreleasepoolobj
組成的結(jié)構(gòu)體蘋果開源代碼
- viewController的生命周期?
(
1
)- initWithNibName:bundle:
(通過.nib創(chuàng)建/init創(chuàng)建時調(diào)用,init
創(chuàng)建時, 也是調(diào)用- initWithNibName:bundle:
, 只不過參數(shù)全部傳入nil); (1-1
)- initWithCoder:
(storyboard
創(chuàng)建時, 那個storyboard
會在自己內(nèi)部生成一個nib
, 將nib
放入一個coder
中); (2
)- awakeFromNib:
; (3
)- loadView:
當(dāng)需要用到view的時候,但是view還沒有初始化時會調(diào)用; (4
)- viewDidLoad:
view已經(jīng)加載完畢; (5
)- viewWillAppear
view即將顯示; (6
)- updateViewConstrains:
更新view的約束; (7
)- viewWillLayoutSubviews
; (8
)- viewDidLayoutSubviews:
; (9
)- viewDidAppear:
視圖已經(jīng)完全展示; (10
)- viewWillDisappear:
視圖即將消失; (11
)- viewDidDisappear:
視圖已經(jīng)完全消失; (12
)dealloc
.