1、#import和#include的區別,@class代表什么?
指令#import和#include都是用于包含頭文件的,前者是保證只會包含一次,不會重復包含;后者是C語言
中原來就有的包含頭文件的指令,在OC開發中,若是C文件,一般會使用#include指令來包含頭文件,為了防止
重復包含,通常會加上條件編譯。
@class是聲明在類前的指令,相當于告訴編譯器有這樣的一個類;但是類的定義在后面提供。在編譯時期,
編譯器看到@class指令聲明了對應的類型,是可以正常編譯的。這是很常用的指令,主要是防止循環引用。
2、OC的內存管理方式以及過程。
內存管理黃金法則:誰使對象的引用計數+1,誰就負責管理使該對象的引用計數-1.
內存管理的過程:在MRC下,對于需要手動釋放的對象的內存管理,我們通過release使對象引用計數-1,
若其引用計數變為0,則對象會被立刻釋放掉。對于autorelease交給自動釋放池管理的對象,每個run loop
循環結束就會去自動釋放池中使所有autorelease類型對象的引用計數-1;若變成0,則釋放之。在ARC下,我
們不能直接調用retain/release來管理釋放,都是交給自動釋放池來管理的。因此,若創建臨時變量,想要使
用完就釋放之,需要在臨時變量放到新創建的自動釋放池里,這樣就可以使用完后就到達了自動釋放池的一個循
環,就會去使對象引用計數-1,變成0后釋放。
最后:對于交給自動釋放池管理的對象,是在每個run loop事件循環結束時才會去使對象引用計數-1,此
時引用計數為0的才會得到釋放。
3、OC中有私有方法嗎?私有變量呢?
在OC中,沒有實實存在的私有方法。通常所謂的私有方法就是放在.m文件中聲明和實現,外部不能直接看到
而已,但是若我們知道有這么一個API,我們是可以調用的。比如,在蘋果上架會因為使用了蘋果的所謂的私有
API而被拒,而這個所謂的私有API就是指蘋果沒有公示出來,但是我們通過其他方式可以看到蘋果的內部有這樣
一個API可以實現某些不公開的功能。
私有變量是有的,可以通過@private來聲明私有變量。比如:
@interface HYBTestModel:NSObject {
@private NSString *_privateName;
}
4、OC中有多繼承嗎?沒有的話用什么代替?
OC中沒有多繼承,這是去掉C++中多繼承的特性,改成使用protocol來代替。Cocoa中所有的類都是
NSObject的子類,這是正確的。
5、淺拷貝與深拷貝的區別是什么?
淺拷貝就是指針拷貝(指向原有內存空間),而深拷貝是內容拷貝(有新的內存空間)。
6、屬性readwrite、readonly、assign、retain、copy、nonatomic各是什么作用,在哪種情況下使用?
作用分別是:
? readwrite:代表可讀可寫,會生成getter和setter方法。
? readonly:代表只讀,只生成getter方法,不會生成setter方法。
? assign:修飾基本數據類型(NSInteger,CGFloat)和C數據類型(int,float,double,char)等。
? retain:MRC下才能手動使用,與ARC下的strong一樣,指定強引用,引用計數+1.
? copy:代表拷貝,也是強引用,引用計數+1,進行指針拷貝。
? nonatomic:代表非原子操作,非線程安全,但可提高性能。
7、什么情況使用weak關鍵字,相比assign有什么不同?
使用weak關鍵字的主要場景:
? 在ARC下,在有可能出現循環引用的時候往往要通過讓其中一端使用weak來解決,比如:delegate代理屬
性,通常就會聲明為weak。
? 自身已經對它進行一次強引用,沒有必要再強引用一次時也會使用weak。比如:自定義IBOutlet控件屬性
一般也使用weak,當然也可以使用strong。
? weak關鍵字只能用于對象,對于基本類型不能使用。
? assign既可以用于對象,也可以用于基本類型,但是只是簡單地進行賦值操作而已。
8、@synthesize和@dynamic分別有什么作用?
分析:@property有兩個對應的詞,一個是@synthesize,另一個是@dynamic。
? @synthesize的語義是如果你沒有手動實現setter方法和getter方法,那么編譯器會自動為你加上
這兩個方法。
? @dynamic告訴編譯器:屬性的setter與getter方法由用戶自己實現,不自動生成,假如一個屬性被
聲明為@dynamic var,然后你沒有提供@setter方法和@getter方法,編譯的時候沒有問題,但是當程序
運行到instance.var=someVar,由于缺setter方法會導致程序崩潰;或者當運行到someVar=var時,由
于缺getter方法同樣會導致崩潰。編譯時沒問題,運行時才執行相應的方法,這就是所謂額動態綁定。
9、OC中的類方法(加號方法)和實例方法(減號方法)有什么本質區別和練習?
類方法:
? 類方法是屬于類對象的(所謂的類對象,不是class instance)
? 類方法只能通過類對象調用
? 類方法中的self是類對象
? 類方法可以調用其他的類方法
? 類方法中不能訪問成員變量
? 類方法中不能直接調用對象方法
實例方法:
? 實例方法是屬于實例對象的
? 實例方法只能通過實例對象調用
? 實例方法中的self是實例對象
? 實例方法中可以訪問成員變量
? 實例方法中直接調用實例方法
? 實例方法中也可以調用類方法(通過類名)
10、線程和進程的區別和聯系?
區別:
① 進程:一個具有一定獨立功能的程序關于某個數據集合的一次運行活動??梢岳斫獬梢粋€運行中的應用程序。
② 線程:程序執行流的最小單元,線程是進程中的一個實體。
聯系:
① 一個進程至少擁有一個線程——即主線程,也可以擁有多個線程。
② 一個線程必須有一個父進程,多個進程可以并發執行。
③ 一個線程可以創建和撤銷另一個線程。
④ 同一個進程中的多個線程之間可以并發執行。
11、iOS中的多線程
iOS中的多線程:是Cocoa框架下的多線程,通過Cocoa的封裝,可以讓我們更為方便的使用線程,做過
C++的可能會對多線程有更多的理解,比如:線程的創立,信號量、共享量有認識,Cocoa框架下會方便很多,
它對線程做了封裝,有些封裝,可以讓我們創建的對象,本身便擁有線程,也就是線程的對象化抽象,從而減
少我們的工程,提供程序的健壯性。
GCD是(Grand Central Dispatch)的縮寫,從系統級別提供的一個易用地多線程類庫,具有運行時
的特點,能充分利用多核心硬件。GCD的API接口為C語言的函數。函數參數中多數有Block,關于Block的使
用參看這里,為我們提供強大的“接口”,對于GCD的使用參見本文。
NSOperation與Queue
NSOperation是一個抽象類,它封裝了線程的細節實現,我們可以通過子類化該對象,機上NSQueue來
同面向對象的思維,管理多線程程序。具體可參看這里:一個機遇NSOperation的多線程網絡訪問的項目。
NSThread
NSThread是一個控制線程執行的對象,它不如NSOperation抽象,通過它我們可以方便的得到一個線程,
并控制它。但NSThread得線程之間的并發控制,是需要我們自己來控制的,可以通過NSCondition實現。
參看
iOS多線程編程之NSThread的使用
定時器與線程的區別:
? 定時器:可以執行多次,默認在主線程中。
? 線程:只能執行一次。
12、串行/并行/同步異步
? 串行/并行
① 串行:一次只能執行一個任務。
② 并行:并行是一次能執行多個任務。
? 并行/并發
① 并行是CPU的多核芯同時執行多個任務。
② 并發是單核CPU交替執行兩個任務。
? 同步異步關注的是消息通訊機制
① 同步:一個線程要等待上一個線程執行完之后才能執行當前的線程,生活中的例子(上廁所)。
② 異步:同時去做兩件或者多件事,比如邊聽歌邊看報。
13、多線程編程
? NSThread:當需要進行一些耗時操作時,會把耗時的操作放到線程中。線程同步:多個線程同時訪問一個
數據會出問題,NSLock、線程同步塊、@synchronize(self){}。
? NSOperationQueue操作隊列(不需要考慮線程同步問題)。編程的重點都放在main里面,
NSInvocationOperation、BSBLockOPeration、自定義Operation。創建一個操作綁定相應的方法,當把
操作添加到操作隊列中時,操作綁定的方法就會自動執行了,當把操作添加到操作隊列中時,默認會調用main方
法。
? GCD(Grand Central Dispatch)宏大的中央調度,串行隊列、并發隊列、主線程隊列;
必須回到主線程刷新UI。
14、三種多線程的對比
1?? NSThread
每個NSThread對象對應一個線程,真正最原始的線程。
1)優點:NSThread輕量級最低,相對簡單。
2)缺點:手動管理所有的線程活動,如生命周期、線程同步、睡眠等。
2?? NSOperation
自帶線程管理的抽象類。
1)優點:自帶線程周期管理,操作上可更注重自己邏輯。
2)缺點:面向對象的抽象類,只能實現它或者使用它定義好的兩個子類:NSInvocationOperation和
NSBlockOperation。
3?? GCD
Grand Central Dispatch(GCD)是Apple開發的一個多核編程的解決方法。
1)優點:最高效,避開并發陷阱。
2)缺點:基于C實現。
15、block和weak修飾符的區別:
① __block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本數據類型。
② __weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基本數據類型(int)。
③ __block對象可以在block中被重新賦值,__weak不可以。
16、static關鍵字的作用
① 函數體內static變量的作用范圍為該函數體,不同于auto變量,該變量的內存只被分配一次,因此其值在
下次調用時仍維持上次的值;
② 在模塊內的static全局變量可以被模塊內所有函數訪問,但不能被模塊外其他函數訪問;
③ 在模塊內的static函數只可被這一模塊內的其他函數調用,這個函數的使用范圍被限制在聲明它的模塊內;
④ 在類中的static成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝;
⑤ 在類中的static成員函數屬于整個類所擁有,這個函數不接收this指針,因而只能訪問類的static成員
變量。
17、簡述類目category優點和缺點。
優點:
? 不需要通過增加子類而增加現有類的行為(方法),且類目中的方法與原始類方法基本沒有區別;
? 通過類目可以將龐大一個類的方法進行劃分,從而便于代碼的日后的維護、更新以及提高代碼的閱讀性;
缺點
? 無法向類目添加實例變量,如果需要添加實例變量,只能通過定義子類的方式;
? 類目中的方法與原始類以及父類方法相比具有更高優先級,如果覆蓋父類的方法,可能導致super消息
的斷裂。因此,最好不要覆蓋原始類中的方法。
18、類別(延展)的作用
? 給系統原有類添加方法,不能擴展屬性。如果類別中方法的名字跟系統的方法名一樣,在調用的時候類別
中的方法優先級更高;
? 分散類的實現,如:
+(NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section
原本屬于NSIndexPath的方法,但因為這個方法經常使用表的時候調用、跟表的關系特別密切,因此把這
個方法以類別的形式、聲明在UITableView.h中。
? 聲明私有方法,某一個方法只實現,不聲明,相當于私有方法。
? 類別不能聲明變量,類別不可以直接添加屬性。property描述setter方法,就不會報錯。
19、循環引用的產生原因,以及解決方法。
產生原因:
對象A和對象B相互引用了對方作為自己的成員變量,只有自己銷毀的時候才能將成員變量的引用計數-1.對象A
的銷毀依賴于對象B的銷毀,同時對象B銷毀也依賴于對象A的銷毀,從而形成循環引用;此時,即使外界沒有任
何指針訪問它,它也無法釋放。
解決方法:
? 事先知道存在循環引用的地方,在合理的位置主動斷開一個引用,是對象回收;
? 使用弱引用的方法。
20、代理的作用
? 代理又叫委托,是一種設計模式,代理是對象與對象之間的通信交互,代理解除了對象之間的耦合性。
? 改變或傳遞控制鏈,允許一個類在某些特定時刻通知到其他類,而不需要獲取到那些類的指針。可以減少
框架復雜度。
? 另外一點,代理可以理解為Java中的回調監聽機制的一種類似。
? 代理的屬性常是assign的原因:防止循環引用,以致對象無法得到正確的釋放。
21、NSNotification、Block、Delegate和KVO的區別
? 代理是一種回調機制,且是一對一的關系,通知是一對多的關系,一個對向所有的觀察者提供變更通知;
? 效率:Delegate比NSNotification高;
? Delegate和Block一般是一對一的通信;
? Delegate需要定義協議方法,代理對象實現協議方法,并且需要建立代理關系才可以實現通信;
? Block更加簡潔,不需要定義繁瑣的協議方法,但通信事件比較多的話,建議使用Delegate。
22、KVC和KVO
KVC、KVO概述:
① KVC(NSKeyValueCoding)“鍵—值 編碼”是一種間接訪問對象的屬性的機制,在OC2.0之后系統提供
了(.)語法來訪問屬性,再此之前我們需要用KVC來訪問。
② KVO(NSKeyValueObserving)“鍵-值 監聽”定義了這樣一種機制,當對象屬性值發生變化的時候我們
能收到一個通知。
③ KVC是一種間接訪問對象屬性的機制。
④ KVO是基于KVC來實現的。
23、謂詞的認識
Cocoa框架中提供了一個NSPredicate的類,該類主要用于指定過濾器的條件,每一個對象通過謂詞進行篩選,
判斷條件是否匹配。
24、@public、@protected、@private它們的含義與作用
? @public:對象的實例變量的作用域在任意地方都可以被訪問;
? @protected:對象的實例變量作用域在本類和子類都可以被訪問;
? @private:實例變量的作用域只能在本類(自身)中訪問。
25、isMemberOfClass和isKindOfClass聯系與區別
? 聯系:兩者都能檢測一個對象是否是某個類的成員。
? 區別:isKindOfClass不僅用來確定一個對象是否是一個類的成員,也可以用來確定一個對象是否派生自
該類的類的成員,而isMemberOfClass只能做到第一點。
? 舉例:如ClassA派生自NSObject類,ClassA *a=[[ClassA alloc]init],
[a isKindOfClass:[NSObject class]]可以檢查出a是否是NSObject派生類的成員,
但isMemberOfClass做不到。
26、UITableViewCell上有個UILabel,顯示NSTimer實現的秒表時間,手指滾動cell過程中,label是否刷,為什么?
這是否刷新取決于timer加入到Run Loop中的Mode是什么。Mode主要是用來指定事件在運行循環中的優先級,
分為:
? NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默認,空閑狀態;
? UITrackingRunLoopMode:ScrollView滑動時會切換到該Mode;
? UIInitalizationRunLoopMode:run loop啟動時,會切換到該mode;
? NSRunLoopCommonModes(kCFRunLoopCommonModes):mode集合。
蘋果公開提供的Mode有兩個:
? NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
? NSRunLoopCommonModes(kCFRunLoopCommonModes)
? 在編程中:如果我們把一個NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
添加到主運行循環中的時候,ScrollView滾動過程中會因為Mode的切換,而導致NSTimer將不再被調度。當
我們滾動的時候,也不希望不調度,那就應該使用默認模式。但是,如果希望在滾動時,定時器也要回調,那就
應該使用common mode。
27、TCP和UDP的區別與聯系
? TCP為傳輸控制協議,為面向連接、可靠的、點到點的通信;
? UDP為用戶數據報協議,非連接的不可靠的點到多點的通信;
? TCP側重可靠傳輸,UDP側重快速傳輸。
28、TCP連接的三次握手
? 第一次握手:客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認;
? 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包,即
SYN+ACK包,此時服務器進入SYN+RECV狀態;
? 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此發送完畢,
客戶端和服務器進入ESTABLISHED狀態,完成三次狀態。
29、ASIHttpRequest、AFNetWorking之間的區別
? ASIHttpRequest功能強大,主要是在MRC下實現的,是對系統CFNetwork API進行了封裝,支持HTTP
協議的CFHTTP,配置比較復雜,并且ASIHttpRequest框架默認不會幫你監聽網絡改變,如果需要讓
ASIHttpRequest幫你監聽網絡狀態改變,并且手動開始這個功能。
? AFNetWorking構建于NSURLConnection、NSOperation以及其他熟悉的Foundation技術之上。擁有
良好的架構,豐富的API及模塊構建方式,使用起來非常輕松。它基于NSOperation封裝的,
AFURLConnectionOperation子類。
? ASIHttpRequest是直接操作對象ASIHttpRequest,是一個實現了NSCoding協議的NSOperation
子類;
AFNetWorking直接操作對象的AFHttpClient,是一個實現NSCoding和NSCopying協議的NSObject子類。
? 同步請求:ASIHttpRequest直接通過調用一個startSynchronous方法;AFNetWorking默認沒有
封裝同步請求,如果開發者需要使用同步請求,則需要重寫getPath:paraments:success:failures方法,
對于AFHttpRequestOperation進行同步處理。
? 性能對比:AFNetWorking請求優于ASIHttpRequest;
30、AFNetWorking大致原理
AFNetWorking是對NSURLConnection和NSURLSession的各自的一層包裝:
① 寫一個單例,開辟新的線程,保證安全性以及開辟一塊內存空間;
② AFN內部開了一條專門用來訪問網絡請求的線程,使用NSThread;
③ 添加一個RunLoop,保證執行網絡獲取。
31、如何進行真機調試
① 首先需要用鑰匙串創建一個鑰匙(key);
② 將鑰匙串上傳到官網,獲取iOS Development證書;
③ 創建APP ID即我們應用程序中的Boundle ID;
④ 添加Device ID即UDID;
⑤ 通過勾選前面所創建的證書:APP、ID、Device ID;
⑥ 生成mobileprovision文件;
⑦ 先決條件:申請開發者賬號99$/299$,從Xcode7開始可以免費真機測試;
⑧ 注意:個人版(99$)可以上架AppStore,企業版(299$)不可以上架AppStore,通過企業分發形式
安裝,將IPA放在七牛云存儲/蒲公英等等。
32、APP發布的上架流程
注意:個人版(99$)可以上架AppStore,企業版(299$)不可以上架AppStore,通過企業分發形式安裝,
將IPA放在七牛云存儲/蒲公英等等。
① 登錄應用發布網站添加應用信息;
② 下載安裝發布證書;
③ 選擇發布證書,使用Archive編譯發布包,用Xcode將代碼(發布包)上傳到服務器;
④ 等待審核通過;
⑤ 生成IPA:菜單欄->Product->Archive。
33、如何進行網絡消息推送
http://upload-images.jianshu.io/upload_images/326255-1d3791a138d9992b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240
APP端需要做的:
① APP ID(唯一標識一個APP程序);
② Provisioning Profile(APP程序的發布需要它,所以推送通知只能在真機上測試);
③ Device Token(設備標識,這個是推送通知功能中特有的)。
后臺需要的:
① SSL Certificate 授權證書
② Private Key
推送的所有步驟:
* Provider:應用自己的服務器;
* APNS:Apple Push Notification Service的簡稱,蘋果的PUSH服務器。
① 移動設備應用啟動時注冊消息推送;
② APNS返回該設備注冊的唯一設備標示deviceToken;
③ 移動設備向Provide提供deviceToken;
④ Provide向APNS發送<SSL Certificate>和<Private Key>以及需要<推送給設備的消息>;
⑤ APNS將消息根據deviceToken推送給指定設備。
34、SDWebImage內部實現流程
SDWebImage:一個異步下載圖片并且支持緩存的UIImageView分類。
① 先從內存圖片緩存查找是否有圖片,如果內存中已經有圖片緩存,SDImageCacheDelegate回調
imageCache:didFindImage:forKey:userInfo:到SDWebImageManager,并展示圖片;
② 如果緩存中沒有,生成NSInvocationOperation添加到隊列開始從硬盤查找圖片是否已經緩存;
③ 根據URLKey在硬盤緩存目錄下嘗試讀取圖片文件,這一步是在NSOperation進行的操作,所以會主線程
進行回調notifyDelegate;
④ 如果有圖片就展示;
⑤ 如果沒有,共享或重新生成一個下載器SDWebImageDownloader開始下載圖片;
⑥ connectionDidFinishLoading:數據下載完成后交給SDWebImageDecoder做圖片解碼處理;
⑦ 圖片解碼處理在一個NSOperationQueue完成,不會拖慢主線程UI。如果有需要對下載的圖片進行二次
處理,最好也在這里完成,效率會好很多;
⑧ 成功后通知所有的downloadDelegates下載完成,回調給需要的地方展示圖片;
⑨ 將圖片保存到SDImageCache中,內存緩存和硬盤緩存同時保存。寫文件到硬盤也可以單獨
NSInvocationOperation完成,避免拖慢主線程。
35、對NSUserDefaults的理解
NSUserDefaults:系統提供的一種存儲數據的方式,主要用于保存少量的數據,默認存儲到library下的
Preferences文件夾。
36、對沙盒的理解
每個iOS應用 都被限制在“沙盒”中,沙盒相當于一個加了僅主人可見權限的文件夾,即是在應用安裝過程中,
系統為每個單獨的應用程序生成它的主目錄和一些關鍵的子目錄。蘋果對沙盒有幾條限制:
① 應用程序在自己的沙盒中運作,但是不能訪問任何其他應用程序的沙盒;
② 應用之間不能共享數據,沙盒里的文件不能被復制到其他應用程序的文件夾中,也不能把其他應用文件夾復制
到沙盒中;
③ 蘋果禁止任何讀寫沙盒以外的文件,禁止應用程序將內容寫到沙盒以外的文件夾中;
④ 沙盒目錄里有三個文件夾:
? Documents——存儲應用程序的數據文件,存儲用戶數據或其他定期備份的信息;
? Library——下有兩個文件夾:Caches——存儲應用程序再次啟動所需的信息,Preferences——包含應用程
序的偏好設置文件,不可在這更改偏好設置;
? temp——存放臨時文件即應用程序再次啟動不需要的文件。
? 獲取沙盒根目錄的方法,有幾種方法:用NSHomeDirectory獲取。
? 獲取Document路徑:NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,YES).
37、堆和棧的區別:
? 棧區(stack)由編譯器自動分配釋放,存放方法(函數)的參數值,局部變量的值等,棧是向低地址
擴展的數據結構,是一塊連續的內存的區域。即棧頂的地址和棧的最大容量是系統預先規定好的。
? 堆區(heap)一般由程序員分配釋放,若程序員不釋放,程序結束時由OS回收,向高地址擴展的數據
結構,是不連續的內存區域,從而堆獲得的空間比較靈活。
? 碎片問題:對于堆來講,頻繁的new/delete勢必會造成內存空間的不連續,從而造成大量的碎片,
使程序效率降低。對于棧來講,則不會存在這個問題,因為棧是先進后出的隊列,他們是如此的一一對應,
以至于永遠都不可能有一個內存塊從棧中間彈出。
? 分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是
編譯器完成的,比如局部變量的分配。動態分配由alloca函數進行分配,但是棧的動態分配和堆是不同的,他的
動態分配是由編譯器進行釋放,無需我們手工實現。
? 分配效率:棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的
地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很
復雜的。
? 全局區(靜態區)(static),全局變量和靜態變量的儲存是放在一塊的,初始化的全局變量和靜態變量
在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束后由系統釋放。
? 文字常量區——常量字符串就是放在這里的,程序結束后由系統釋放。
? 程序代碼區——存放函數體的二進制代碼。
38、Struct與Class的區別:
(http://blog.csdn.net/yuliu0552/article/details/6717915)
共同點:
① 都可以包含成員函數;
② 都能繼承;
③ 都能實現多態。
區別:
struct是public的,class是private的。
① **struct作為數據結構的實現體,它默認的數據訪問控制是public的;而class作為對象的實現體,
它默認的成員變量訪問控制是private的**。
② 當你覺得你要做的更像是一種數據結構的話,那么用struct;如果你要做的更像是一種對象的話,那么用
class。
③ struct更適合看成是一個數據結構的實現體,class更適合看成是一個對象的實現體。
39、介紹一下觀察者模式
① 含義:當對象間存在一對多關系時,則使用觀察者模式(Observer pattern)。比如,當一個對象被修改
時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。
② 何時使用:一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察著對象)都將得到通知,進行廣播
通知。
③ 舉例子:西游記里面悟空請求菩薩降服紅孩兒,菩薩灑了一地水招來一個老烏龜,這個烏龜就是觀察者,
他觀察菩薩灑水這個動作。
④ 使用場景:
? 有多個子類共有的方法,且邏輯相同。
? 重要的、復雜的方法,可以考慮作為模板方法。
優缺點:
優點:① 觀察者和被觀察者是抽象耦合的。
② 建立一套觸發機制。
缺點:① 如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
② 如果在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發他們之間進行循環調用,可能導致系統
崩潰。
③ 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發生變化的,而僅僅只是知道觀察
目標發生了變化。
iOS觀察者模式:
① 在iOS中觀察者模式的實現有三種方法:Notification、KVO以及標準方法。
② 標準方法:標準方法的實現是這樣的:Subject(主題)知道所有的觀察者,但是不知道他們的類型。
下面我們就從創建Subject和Observer(觀察者)的協議(protocol)開始。