設計模式
1.delegate和notification什么區(qū)別灭红,什么情況使用?
2.描述一下KVO和KVC眶掌。
Key-Value Observing (簡寫為KVO):當指定的對象的屬性被修改了荒吏,允許對象接受到通知的機制驱还。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察者精堕。
KVC是KeyValue Coding的簡稱孵淘,它是一種可以直接通過字符串的名字(key)來訪問類屬性的機制。而不是通過調(diào)用Setter歹篓、Getter方法訪問夺英。
3簡述NotificationCenter、KVC滋捶、KVO、Delegate?并說明它們之間的區(qū)別余黎?
答:消息中心重窟,消息通知;
利用鍵-值間接訪問類中的某個屬性
利用鍵-路徑間接訪問類中的某個屬性惧财,也稱觀察者模式
代理巡扇,多用于兩個類之間的傳值
15.你熟悉的設計模式有哪些,請說說對他們的理解垮衷。
答:單例厅翔,通知,KVO搀突,代理刀闷,target-action等
單例,主要特點是一個類只有一個對象。對外提供了一個獲取唯一對象的方法甸昏,一般都是類方法顽分,完整的單例會重寫很多引用計數(shù)相關的方法(比如:allocWithZone,copyWithZone施蜜,retain卒蘸,release,autorelease翻默,retainCount等)以保證對象在任何情況下都唯一缸沃。單例最大的價值就是建立程序級別的全局變量,就是把不同模塊都要用的變量以屬性的形式放到單例里面修械,以便隨時使用趾牧。音頻播放類程序一般會寫單例來管理需要播放的音樂信息,需要下載的地方也會以單例的形式來管理下載對象祠肥。
通知武氓,是M與C通信的方式之一。一般是Model發(fā)送變化的時候仇箱,會發(fā)送通知告訴Controller县恕,Controller再做相應的處理。需要先往通知中心里面注冊觀察者剂桥,然后在合適的時機忠烛,通知中心post通知,觀察者做對應的處理权逗,當觀察者將要釋放的時候美尸,從通知中心移除觀察者。
KVO斟薇,也是M與C通訊的方式师坎。一般是C去觀察M的某個屬性,某個屬性發(fā)生變化之后堪滨,C做出相應的處理胯陋,當C將要釋放的時候,M移除觀察者袱箱。
代理遏乔,是V與C通信的方式之一。一般C是V的代理发笔,V發(fā)生變化的時候盟萨,C做對應的調(diào)整。例如:UITableView被點擊了了讨,由Controller做處理捻激。我們在自己寫代理的時候制轰,一定要清楚誰來處理事件,誰來調(diào)用代理方法铺罢。通常情況下都是C處理時間艇挨,V在適當?shù)臅r候調(diào)用代理方法。
target-action韭赘,也是V與C通信的方式之一缩滨。一般C是V的target,V被點擊或者被滑動之后泉瞻,C做出對應的處理脉漏。無論是target-action還是代理,核心都是回調(diào)。
8.在使用系統(tǒng)的一些類例如UITableView時,會發(fā)現(xiàn)其delegate屬性的語義設置為assign而不是retain翰守,為什么呢?
答:delegate的語義修飾符 為assign不是retain主要是為了避免兩個對象因相互引用造成的內(nèi)存泄露問題司忱。
因為retain修飾delegate,當通過set方法賦值時畴蹭,對象的引用計數(shù)會+1.
如果此時兩個對象具有如下關系:A對象有一個屬性是B坦仍,B的delegate是A。即互相為彼此的屬性叨襟。例如:A是viewController繁扎,B是tableView. ?B是A的屬性,B的引用計數(shù)會+1糊闽,B的delegate是A梳玫,A的引用計數(shù)也會+1.那么如果A沒有釋放,B就一直不會釋放右犹,因為A對B有擁有權提澎。 同理,B沒有釋放念链,A也一直釋放不掉虱朵,因為B對A也有擁有權。 因此A和B的dealloc都會不執(zhí)行钓账,造成內(nèi)存泄露.
代碼演示如下(只寫出了核心代碼):
A *a = ?[[A alloc] init] // a引用計數(shù):1
B *b = ?[[B alloc] init] // b引用計數(shù):1
a.b = b; // b引用計數(shù):2
b.delegate = a; // a引用計數(shù):2
[a release]; // a引用計數(shù):1
[b release]; // b引用計數(shù):1
//最終A和B都釋放不掉。
assign則是直接賦值絮宁,并不會引起引用計數(shù)增加梆暮,因此使用assign不會出現(xiàn)內(nèi)存泄露。
代碼演示如下(只寫出了核心代碼):
A *a = ?[[A alloc] init] // a引用計數(shù):1
B *b = ?[[B alloc] init] // b引用計數(shù):1
a.b = b; // b引用計數(shù):2
b.delegate = a; // a引用計數(shù):1
[a release]; // a引用計數(shù):0绍昂,b引用計數(shù):1(在a的dealloc里面_b被釋放了)
[b release]; // b引用計數(shù):0
//最終A和B都可以釋放掉啦粹。
13.NSNotification和KVO的區(qū)別和用法是什么?什么時候應該使用通知,什么時候應該使用KVO,它們的實現(xiàn)上有什么區(qū)別?
答:通知和KVO都是觀察者模式的體現(xiàn)偿荷,二者側(cè)重點有些不同。
通知往往用于1對多的場景唠椭,多個觀察者觀察一個通知跳纳,一旦這個通知被通知中心post,所有觀察者都可以做出響應贪嫂。具體的實現(xiàn)流程是:(1)通知中心通過addObserver方法添加觀察者寺庄,其實是把觀察者和通知進行綁定,多次使用addObserver方法可以為同一個通知添加多個觀察者力崇。(2)通知中心發(fā)送通知斗塘。(3)各個觀察者做各自的處理。(4)在觀察者銷毀之前(dealloc中)亮靴,從通知中心移除觀察者馍盟。
KVO多用于1對1的場景,一個對象去觀察另外一個對象的屬性值有沒有發(fā)生變化茧吊,一旦發(fā)生變化贞岭,觀察者做出響應。具體的流程是:(1)被觀察者添加觀察者搓侄,指定觀察者觀察的屬性瞄桨。(2)被觀察者的屬性在某一時間發(fā)生了變化。(3)觀察者做出響應休讳。(4)在觀察者銷毀之前讲婚,先移除觀察者。
KVO其實也可以1對多俊柔,就是多個觀察者觀察同一個對象同一個屬性的變化筹麸。KVO和通知給人的感覺一個主動通知(通知會由通知中心主動post),一個是被動通知(KVO雏婶,觀察者一直盯著屬性變沒變物赶,一旦變化,自己就做出響應留晚。被觀察的對象不是主動告知你我變了)酵紫。
23.定義一個返回值為字符串類型,參數(shù)是int類型的Block错维。并且調(diào)用該Block奖地。
答:Block定義如下所示:
NSString * (^block)(int a) = ^ NSString * (int a){
return [NSString ?stringWithFormat:“%d”,a];
};
Block調(diào)用:
NSString *str = block(10);
24.請談談你對block和delegate模式認識赋焕?
答:無論是block還是delegate模式本質(zhì)上都是回調(diào)参歹,使用block,其優(yōu)點是回調(diào)的block代碼塊直接就放在了block賦值的地方隆判,使代碼更為緊湊犬庇,缺點是block內(nèi)使用到當前類的實例變量的時候僧界,需要注意循環(huán)引用的問題,即需要使用__block(MRC下)或者__weak(ARC下)定義一個弱引用的self出來臭挽,block里面使用弱引用的self去操作屬性或調(diào)用方法捂襟。delegate模式不用像block一樣做特殊處理,但是如果多個對象設置的代理是同一個對象欢峰,就需要在delegate方法中判斷當前執(zhí)行代理的是哪個對象葬荷。
1、block的作用赤赊?
1.__block對象在block中是可以被修改闯狱、重新賦值的;
2.__block對象在block中不會被block強引用一次抛计,從而不會出現(xiàn)循環(huán)引用的問題哄孤。
2、block里面能不能修改靜態(tài)變量(能吹截,__block可以)為什么要用__block
你可以指定引入一個變量為可更改的,即讀-寫的,通過應用__block存儲類型修 飾符瘦陈。局部變量的__block的存儲和register、auto波俄、static等存儲類型相似,但它們之 間不兼容晨逝。
__block變量保存在變量共享的作用域范圍內(nèi),所有的blocks和block副本都聲明 或創(chuàng)建在和變量的作用域相同范圍內(nèi)。所以,如果任何blocks副本聲明在棧內(nèi)并未超 出棧的結束時,該存儲會讓棧幀免于被破壞(比如封裝為以后執(zhí)行)懦铺。同一作用域范 圍內(nèi)給定的多個block可以同時使用一個共享變量
作為一種優(yōu)化,block存儲在棧上面,就像blocks本身一樣捉貌。如果使用Block_copy拷貝了block的一個副本(或者在Objective-C里面給block發(fā)送了一條copy消息),變量會被拷貝到堆上面。所以一個__block變量的地址可以隨時間推移而被更改冬念。
使用__block的變量有兩個限制:它們不能是可變長的數(shù)組,并且它們不能是包 含有C99可變長度的數(shù)組變量的數(shù)據(jù)結構趁窃。
3、聲明一個block
聲明block
int (^myblock) (int)
說明:第一個int是block的返回值myblock是block變量 ? ? 第二個int是參數(shù)
//舉例
在.h中
typedef void(^MyBlock)(int value);
@property (nonatomic,weak) MyBlock block;
-(void)setMyBlock:(void(^)(int value)) block;
在.m中
-(void)setMyBlock:(void(^)(int value)) block {
if (block) {
self.block=block;
}
}
11急前、ios使用block應當注意什么醒陆?
(1)block在實現(xiàn)時就會對它引用到的它所在方法中定義的棧變量進行一次只讀拷貝,然后在block塊內(nèi)使用該只讀拷貝裆针。
(2)非內(nèi)聯(lián)(inline)block不能直接訪問self刨摩,只能通過將self當作參數(shù)傳遞到block中才能使用,并且此時的self只能通過setter或getter方法訪問其屬性世吨,不能使用句點式方法澡刹。但內(nèi)聯(lián)block不受此限制。
(3)使用weak–strong dance技術來避免循環(huán)引用
(4)block內(nèi)存管理分析
block其實也是一個NSObject對象耘婚,并且在大多數(shù)情況下像屋,block是分配在棧上面的,只有當block被定義為全局變量或block塊中沒有引用任何automatic變量時边篮,block才分配在全局數(shù)據(jù)段上己莺。__block變量也是分配在棧上面的。在ARC下戈轿,編譯器會自動檢測為我們處理了block的大部分內(nèi)存管理凌受,但當將block當作方法參數(shù)時候,編譯器不會自動檢測思杯,需要我們手動拷貝該block對象胜蛉。
在ARC下,對block變量進行copy始終是安全的色乾,無論它是在棧上誊册,還是全局數(shù)據(jù)段,還是已經(jīng)拷貝到堆上暖璧。對棧上的block進行copy是將它拷貝到堆上案怯;對全局數(shù)據(jù)段中的block進行copy不會有任何作用;對堆上的block進行copy只是增加它的引用記數(shù)澎办。
如果棧上的block中引用了__block類型的變量嘲碱,在將該block拷貝到堆上時也會將__block變量拷貝到堆上如果該__block變量在堆上還沒有對應的拷貝的話,否則就增加堆上對應的拷貝的引用記數(shù)局蚀。
http://my.oschina.net/u/1432769/blog/390401
2.kvo除了能觀察屬性外麦锯,能不能觀察對象
不能觀察對象
KVO,即:Key-Value Observing,它提供一種機制琅绅,當指定的對象的屬性被修改后扶欣,則對象就會接受到通知。簡單的說就是每次指定的被觀察的對象的屬性被修改后千扶,KVO就會自動通知相應的觀察者了
KVO是一個對象能夠觀察另外一個對象的屬性的值料祠,并且能夠發(fā)現(xiàn)值的變化。這是一個對象與另外一個對象保持同步的一種方法县貌,即當另外一種對象的狀態(tài)發(fā)生改變時术陶,觀察對象馬上作出反應。它只能用來對屬性作出反應煤痕,而不會用來對方法或者動作作出反應梧宫。
實現(xiàn)原理:當為某一個對象屬性注冊監(jiān)聽的時候,該對象的isa指針就會指向一個中間類摆碉,而不是本來對象真實的類塘匣。所以說,對象的isa指針可以改變巷帝,我們的程序最好不要依賴isa指針忌卤。
簡而言之就是:
1、當一個object有觀察者時楞泼,動態(tài)創(chuàng)建這個object的類的子類
2驰徊、對于每個被觀察的property笤闯,重寫其set方法
3、在重寫的set方法中調(diào)用- willChangeValueForKey:和- didChangeValueForKey:通知觀察者
4棍厂、當一個property沒有觀察者時颗味,刪除重寫的方法
5、當沒有observer觀察任何一個property時牺弹,刪除動態(tài)創(chuàng)建的子類
10浦马、簡述在app中所應用到設計模式
(一)代理模式
應用場景:當一個類的某些功能需要由別的類來實現(xiàn),但是又不確定具體會是哪個類實現(xiàn)张漂。
優(yōu)勢:解耦合
敏捷原則:開放-封閉原則
實例:tableview的 數(shù)據(jù)源delegate晶默,通過和protocol的配合,完成委托訴求航攒。
列表row個數(shù)delegate
自定義的delegate
(二)觀察者模式
應用場景:一般為model層對磺陡,controller和view進行的通知方式,不關心誰去接收屎债,只負責發(fā)布信息仅政。
優(yōu)勢:解耦合
敏捷原則:接口隔離原則,開放-封閉原則
實例:Notification通知中心盆驹,注冊通知中心圆丹,任何位置可以發(fā)送消息,注冊觀察者的對象可以接收躯喇。
kvo辫封,鍵值對改變通知的觀察者,平時基本沒用過廉丽。
(三)MVC模式
應用場景:是一中非常古老的設計模式倦微,通過數(shù)據(jù)模型,控制器邏輯正压,視圖展示將應用程序進行邏輯劃分欣福。
優(yōu)勢:使系統(tǒng),層次清晰焦履,職責分明拓劝,易于維護
敏捷原則:對擴展開放-對修改封閉
實例:model-即數(shù)據(jù)模型,view-視圖展示嘉裤,controller進行UI展現(xiàn)和數(shù)據(jù)交互的邏輯控制郑临。
(四)單例模式
應用場景:確保程序運行期某個類,只有一份實例屑宠,用于進行資源共享控制厢洞。
優(yōu)勢:使用簡單,延時求值,易于跨模塊
敏捷原則:單一職責原則
實例:[UIApplication sharedApplication]躺翻。
注意事項:確保使用者只能通過getInstance方法才能獲得丧叽,單例類的唯一實例。
java公你,C++中使其沒有公有構造函數(shù)蠢正,私有化并覆蓋其構造函數(shù)。
object c中省店,重寫allocWithZone方法,保證即使用戶用alloc方法直接創(chuàng)建單例類的實例笨触,
返回的也只是此單例類的唯一靜態(tài)變量懦傍。
(五)策略模式
應用場景:定義算法族,封裝起來芦劣,使他們之間可以相互替換粗俱。
優(yōu)勢:使算法的變化獨立于使用算法的用戶
敏捷原則:接口隔離原則;多用組合虚吟,少用繼承寸认;針對接口編程,而非實現(xiàn)串慰。
實例:排序算法偏塞,NSArray的sortedArrayUsingSelector;經(jīng)典的鴨子會叫邦鲫,會飛案例灸叼。
注意事項:1,剝離類中易于變化的行為庆捺,通過組合的方式嵌入抽象基類
2古今,變化的行為抽象基類為,所有可變變化的父類
3滔以,用戶類的最終實例捉腥,通過注入行為實例的方式,設定易變行為
防止了繼承行為方式你画,導致無關行為污染子類抵碟。完成了策略封裝和可替換性。
(六)工廠模式
應用場景:工廠方式創(chuàng)建類的實例撬即,多與proxy模式配合立磁,創(chuàng)建可替換代理類。
優(yōu)勢:易于替換剥槐,面向抽象編程唱歧,application只與抽象工廠和易變類的共性抽象類發(fā)生調(diào)用關系。
敏捷原則:DIP依賴倒置原則
實例:項目部署環(huán)境中依賴多個不同類型的數(shù)據(jù)庫時,需要使用工廠配合proxy完成易用性替換
注意事項:項目初期颅崩,軟件結構和需求都沒有穩(wěn)定下來時几于,不建議使用此模式,因為其劣勢也很明顯沿后,
增 加了代碼的復雜度沿彭,增加了調(diào)用層次,增加了內(nèi)存負擔尖滚。所以要注意防止模式的濫用喉刘。
8.使用block和使用delegate完成委托模式有什么優(yōu)點?
委托模式在iOS中大量應用漆弄,其在設計模式中是適配器模式中的對象適配器睦裳,Objective-C中使用id類型指向一切對象,使委托模式更為簡潔撼唾。
block
優(yōu)點:
1.語法簡潔廉邑,實現(xiàn)回調(diào)不需要顯示的調(diào)用方法,代碼更為緊湊倒谷。
2.增強代碼的可讀性和可維護性蛛蒙。
3.配合GCD優(yōu)秀的解決多線程問題。
缺點:
1.Block中得代碼將自動進行一次retain操作渤愁,容易造成內(nèi)存泄露牵祟。
2.Block內(nèi)默認引用為強引用,容易造成循環(huán)引用猴伶。
代理:
優(yōu)點:
1.減少代碼的耦合性课舍,使事件監(jiān)聽和事件處理相分離。
2.清晰的語法定義他挎,減少維護成本筝尾,較強的代碼可讀性。
3.不需要創(chuàng)建第三方來監(jiān)聽事件和傳輸數(shù)據(jù)办桨。
4.一個控制器可以實現(xiàn)多個代理筹淫,滿足自定義開發(fā)需求,可選必選有較大的靈活性呢撞。
缺點:
1.實現(xiàn)委托的代碼過程比較繁瑣损姜。
2.當實現(xiàn)跨層傳值監(jiān)聽的時候?qū)⒓哟蟠a的耦合性,并且程序的層次結構將變的混亂殊霞。
3.當對多個對象同時傳值響應的時候摧阅,委托的易用性將
10.何時使用代理,何時使用通知绷蹲;
代理:一般控件用的比較多棒卷,其實也可以用block實現(xiàn)顾孽,如果實現(xiàn)的接口比較多的話,建議用代理比规,如UITableview若厚。
如果一個類能夠獲取到通知的對象,這種情況下蜒什,我們用代理的效率會更高测秸,而且能夠更好的實現(xiàn)對要代理的對象的管理。
通知:這東西是全局的灾常,而且是同步的霎冯,如果你要全局發(fā)送消息,并且做的事情時間不長钞瀑,不會阻塞線程的話肃晚,建議使用。
如果一個通知的發(fā)送者有多個接受者仔戈,而且接受的位置完全不確定,那么這種情況下用通知是比較好的方式
37. block在ARC中和MRC中的用法有什么區(qū)別,需要注意什么
①.對于沒有引用外部變量的Block拧廊,無論在ARC還是非ARC下监徘,類型都是__NSGlobalBlock__,這種類型的block可以理解成一種全局的block吧碾,不需要考慮作用域問題凰盔。同時,對他進行Copy或者Retain操作也是無效的
②.應注意避免循環(huán)引用
36.類工廠方法是什么
類工廠方法的實現(xiàn)是為了向客戶提供方便倦春,它們將分配和初始化合在一個步驟中户敬, 返回被創(chuàng)建的對象,并
進行自動釋放處理睁本。這些方法的形式是+ (type)className...(其中className不包括任何前綴)尿庐。
工廠方法可能不僅僅為了方便使用。它們不但可以將分配和初始化合在一起呢堰,還可以 為初始化過程提供對
象的分配信息抄瑟。
類工廠方法的另一個目的是使類(比如NSWorkspace)提供單件實例。雖 然init...方法可以確認一
個類在每次程序運行過程只存在一個實例枉疼,但它需要首先分配一個“生的”實例皮假,然后還必須釋放該實例。
工廠 方法則可以避免為可能沒有用的對象盲目分配內(nèi)存骂维。
43.代理和協(xié)議什么區(qū)別
代理是一種概念,協(xié)議是一種技術,代理是用協(xié)議來實現(xiàn)的,代理 是2個對象之間通訊的一種方式惹资。 代理主要做反向傳值的。實現(xiàn)系統(tǒng)的一些回調(diào)方法,比如scrollview滑動事件,選擇照片,asi網(wǎng)絡下載完成等.iOS開發(fā)和Objective-c區(qū)別
50.在block內(nèi)如何修改block外部變量航闺?
默認情況下褪测,在block中訪問的外部變量是復制過去的,即:寫操作不對原變量生效。但是你可以加上__block來讓其寫操作生效汰扭,示例代碼如下:
__block int a = 0;
void ?(^foo)(void) = ^{
a = 1;
}
f00();
//這里稠肘,a的值被修改為1
53.使用block時什么情況會發(fā)生引用循環(huán),如何解決萝毛?
一個對象中強引用了block项阴,在block中又使用了該對象,就會發(fā)射循環(huán)引用笆包。 解決方法是將該對象使用__weak或者__block修飾符修飾之后再在block中使用环揽。
id weak weakSelf = self;或者weak __typeof(&*self)weakSelf = self該方法可以設置宏
id __block weakSelf = self;
block中的weak self,是任何時候都需要加的么庵佣?
(2)block
block在copy時都會對block內(nèi)部用到的對象進行強引用(ARC)或者retainCount增1(非ARC)歉胶。在ARC與非ARC環(huán)境下對block使用不當都會引起循環(huán)引用問題,一般表現(xiàn)為巴粪,某個類將block作為自己的屬性變量通今,然后該類在block的方法體里面又使用了該類本身,簡單說就是self.someBlock = ^(Type var){[self dosomething];或者self.otherVar = XXX;或者_otherVar = ...};block的這種循環(huán)引用會被編譯器捕捉到并及時提醒
95.哪些類不適合使用單例模式肛根?即使他們在周期中只會出現(xiàn)一次辫塌。
工具類,不需要存儲數(shù)據(jù)的.
簡明概要的說明了KVO和NSNotification的區(qū)別:
和delegate一樣,KVO和NSNotification的作用也是類與類之間的通信派哲,與delegate不同的是1)這兩個都是負責發(fā)出通知臼氨,剩下的事情就不管了,所以沒有返回值芭届;2)delegate只是一對一储矩,而這兩個可以一對多。這兩者也有各自的特點褂乍。
1)KVO的使用:
被觀察者發(fā)出addObserver:forKeyPath:options:context:方法來添加觀察者持隧。
然后只要被觀察者的keyPath值變化(注意:單純改變其值不會調(diào)用此方法,只有通過getters和setters來改變值才會觸發(fā)KVO)逃片,就會在觀察者里調(diào)用方法observeValueForKeyPath:ofObject:change:context:
因此觀察者需要實現(xiàn)方法observeValueForKeyPath:ofObject:change:context:來對KVO發(fā)出的通知做出響應舆蝴。
這 些代碼都只需在觀察者里進行實現(xiàn),被觀察者不用添加任何代碼题诵,所以誰要監(jiān)聽誰注冊洁仗,然后對響應進行處理即可,使得觀察者與被觀察者完全解耦性锭,運用很靈活很 簡便赠潦;但是KVO只能檢測類中的屬性,并且屬性名都是通過NSString來查找草冈,編譯器不會幫你檢錯和補全她奥,純手敲所以比較容易出錯瓮增。
2)NSNotification的使用
這里的通知不是由被觀察者發(fā)出,而是由NSNotificationCenter來統(tǒng)一發(fā)出哩俭,而不同通知通過唯一的通知標識名notificationName來區(qū)分绷跑,標識名由發(fā)送通知的類來起。
首先被觀察者自己在必要的方法A里凡资,通過方法postNotificationName:object:來發(fā)出通知notificationName這樣發(fā)送通知者這邊的工作就完成了砸捏,每次A被調(diào)用,就會發(fā)送一次通知notificationName隙赁。
然后誰要監(jiān)聽A的變化垦藏,就通過[NSNotificationCenter defaultCenter]的方法addObserver:selector:name:object:為觀察者注冊監(jiān)聽name為notificationName的通知然后每次發(fā)出name為notificationName的通知時,注冊監(jiān)聽后的觀察者就會調(diào)用其自己定義的方法notificationSelector來進行響應伞访。
NSNotification的特點呢掂骏,就是需要被觀察者先主動發(fā)出通知,然后觀察者注冊監(jiān)聽后再來進行響應厚掷,比KVO多了發(fā)送通知的一步弟灼,但是其優(yōu)點是監(jiān)聽不局限于屬性的變化,還可以對多種多樣的狀態(tài)變化進行監(jiān)聽冒黑,監(jiān)聽范圍廣袜爪,使用也更靈活。
MVC模式及好處薛闪?
MVC是三個單詞的縮寫,分別為:
模型(Model),視圖(View)和控制Controller)。
MVC模式的目的就是實現(xiàn)Web系統(tǒng)的職能分工俺陋。
Model層實現(xiàn)系統(tǒng)中的業(yè)務邏輯豁延,通常可以用JavaBean或EJB來實現(xiàn)腊状。
View層用于與用戶的交互诱咏,通常用JSP來實現(xiàn)。
Controller層是Model與View之間溝通的橋梁缴挖,它可以分派用戶的請求并選擇恰當?shù)囊晥D以用于顯示袋狞,同時它也可以解釋用戶的輸入并將它們映射為模型層可執(zhí)行的操作。
MVC模式的好處
1.各施其職映屋,互不干涉
在MVC模式中苟鸯,三個層各施其職,所以如果一旦哪一層的需求發(fā)生了變化棚点,就只需要更改相應的層中的代碼而不會影響到其它層中的代碼早处。
2.有利于開發(fā)中的分工
在MVC模式中,由于按層把系統(tǒng)開瘫析,那么就能更好的實現(xiàn)開發(fā)中的分工砌梆。網(wǎng)頁設計人員可以進行開發(fā)視圖層中的JSP默责,對業(yè)務熟悉的開發(fā)人員可開發(fā)業(yè)務層,而其它開發(fā)人員可開發(fā)控層咸包。
3.有利于組件的重用
分層后更有利于組件的重用桃序。如控制層可獨立成一個能用的組件,視圖層也可做成通用的操作界面烂瘫。
MVC(Model-View-Controller)應用程序結構被用來分析分布式應用程序的特征媒熊。這種抽象結構能有助于將應用程序分割成若干邏輯部件,使程序設計變得更加容易忱反。
MVC結構提供了一種按功能對各種對象進行分割的方法(這些對象是用來維護和表現(xiàn)數(shù)的)泛释,其目的是為了將各對象間的耦合程度減至最小。MVC結構本來是為了將傳統(tǒng)的輸入(input)温算、處理(processing)怜校、輸出(output)任務運用到圖形化用戶交互模型中而設計的。但是注竿,將這些概念運用于基于Web的企業(yè)級多層應用領域也是很適合的茄茁。
在MVC結構中,模型(Model)代表應用程序的數(shù)據(jù)(data)和用于控制訪問和修改這些數(shù)據(jù)的業(yè)務規(guī)則(business rule)巩割。通常模型被用來作為對現(xiàn)實世界中一個處理過程的軟件近似裙顽,當定義一個模型時,可以采用一般的簡單的建模技術宣谈。
當模型發(fā)生改變時愈犹,它會通知視(View),并且為視提供查詢模型相關狀態(tài)的能力闻丑。同時漩怎,它也為控制器(Controller)提供訪問封裝在模型內(nèi)部的應用程序功能的能力。
一個視(View)用來組織模型的內(nèi)容嗦嗡。它從模型那里獲得數(shù)據(jù)并指定這些數(shù)據(jù)如何表現(xiàn)勋锤。當模型變化時,視負責維持數(shù)據(jù)表現(xiàn)的一致性侥祭。視同時將用戶要求告知控制器(Controller)叁执。
控制器(Controller)定義了應用程序的行為;它負責對來自視的用戶要求進行解釋矮冬,并把這些要求映射成相應的行為谈宛,這些行為由模型負責實現(xiàn)。在獨立運行的GUI客戶端胎署,用戶要求可能是一些鼠標單擊或是菜單選擇操作入挣。在一個Web應用程序中,它們的表現(xiàn)形式可能是一些來自客戶端的GET或POST的HTTP請求硝拧。模型所實現(xiàn)的行為包括處理業(yè)務和修改模型的狀態(tài)径筏。根據(jù)用戶要求和模型行為的結果葛假,控制器選擇一個視作為對用戶請求的應答。通常一組相關功能集對應一個控制器滋恬。
1)各施其職聊训,互不干涉
在MVC模式中,三個層各施其職恢氯,所以如果一旦哪一層的需求發(fā)生了變化带斑,就只需要更改相應的層中的代碼而不會影響到其它層中的代碼。假如業(yè)務發(fā)生了變化勋拟,如在取文章時可能webmaster把一些文章作了無效標志勋磕,不能直接把所有文章取出來,只能取出有效的文章敢靡,這時業(yè)務就發(fā)生了改變挂滓。再設想一下,如果這個業(yè)務邏輯在100個頁面中都要用到啸胧,那么MVC模式就體現(xiàn)了它的靈活性赶站。我們可以不更改任何JSP,只要更改model層中的相應類中的SQL語句即可纺念。
2)有利于開發(fā)中的分工
在MVC模式中贝椿,由于按層把系統(tǒng)開,那么就能更好的實現(xiàn)開發(fā)中的分工陷谱。網(wǎng)頁設計人員可以進行開發(fā)視圖層中的JSP烙博,對業(yè)務熟悉的開發(fā)人員可開發(fā)業(yè)務層,而其它開發(fā)人員可開發(fā)控制層烟逊。
3)有利于組件的重用
分層后更有利于組件的重用渣窜。如控制層可獨立成一個能用的組件,視力層也可做成通用的操作界面
10焙格、聲明block屬性的時候為什么?用copy?
避免block被系統(tǒng)釋放,因為?一開始block是在棧中的,只有copy后的block才會
在堆中。
Block屬性的聲明,?首先需要?用copy修飾符,因為只有copy后的Block才會在堆中,棧中的Block的?生命周期是和棧綁定的,避免編譯器將其釋放;
(拓展)block與線程安全另?一個需要注意的問題是關于線程安全,在聲明Block屬性時需要確認“在調(diào)?用
Block時另?一個線程有沒有可能去修改Block?”這個問題,如果確定不會有這種情況發(fā)?生的話,那么Block屬性聲明可以?用nonatomic夷都。如果不肯定的話(通常情況是這樣的),那么你?首先需要聲明Block屬性為atomic,也就是先保證變量的原?子性(Objective-C并沒有強制規(guī)定指針讀寫的原?子性,C#有)眷唉。
?比如這樣?一個Block類型: typedef void (^MyBlockType)(int);
屬性聲明:
@property (copy) MyBlockType myBlock;
這?里ARC和?非ARC聲明都是?一樣的,當然注意在?非ARC下要release Block。
但是,有了atomic來保證基本的原?子性還是沒有達到線程安全的,接著在調(diào)?用時需要把Block先賦值給本地變量,以防?止Block突然改變囤官。因為如果不這樣的話,即便是先判斷了Block屬性不為空,在調(diào)?用之前,?一旦另?一個線程把Block屬性設空了,程序就會crash,如下代碼:
if (self.myBlock)
{
//此時,?走到這?里,self.myBlock可能被另?一個線程改為空,造成crash //注意:atomic只會確保myBlock的原?子性,這種操作本?身還是?非線程安全的self.myBlock(123);
}
所以正確的代碼是(ARC): MyBlockType block = self.myBlock; //block現(xiàn)在是本地不可變的
if (block)
{ block(123); }
在?非ARC下則需要?手動retain?一下,否則如果屬性被置空,本地變量就成了野指針了,如下代碼:
//?非ARC
MyBlockType block = [self.myBlock retain];
if (block)
{ block(123); }
[block release];
4.(口述)NSNotification和KVO的區(qū)別和用法是什么冬阳?什么時候應該使用通知,什么時候應該使用KVO党饮,它們的實現(xiàn)上有什么區(qū)別嗎肝陪?如果用protocol和delegate(或者delegate的Array)來實現(xiàn)類似的功能可能嗎?如果可能刑顺,會有什么潛在的問題氯窍?如果不能饲常,為什么?
2狼讨、非自動內(nèi)存管理情況下怎么做單例模式
非ARC內(nèi)存管理模式下對象必須手動釋放贝淤,為了防止那個唯一的單例對象被釋放掉,則只需要重寫下面的幾個方法即可
+(instancetype) allocWithZone:(struct _NSZone *)zone
-(instancetype) copyWithZone:(NSZone*)zone
-(id) retain
-(oneway void) release
-(instancetype) autorelease
-(unsigned) retainCount
http://www.cnblogs.com/heyonggang/p/3553840.html
4政供、What is Singleton pattern? Please try to implement one
單例模式的意思就是只有一個實例播聪。單例模式確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例布隔。這個類稱為單例類离陶。
在iOS中,單例有兩種實現(xiàn)方式衅檀。根據(jù)線程安全的實現(xiàn)來區(qū)分招刨,一種是使用@synchronized,另一種是使用GCD的dispatch_once函數(shù)术吝。
要實現(xiàn)單例计济,首先需要一個static的指向類本身的對象,其次需要一個初始化類函數(shù)排苍。下面是兩種實現(xiàn)的代碼沦寂。
1、@synchronized
static InstanceClass *instance;
+ (InstanceClass *)defaultInstance{
@synchronized (self){
if (instance == nil) {
instance = [[InstanceClass alloc] init];
}
}
return instance;
}
2淘衙、GCD
static InstanceClass *instance;
+ (InstanceClass *)defaultInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[InstanceClass alloc] init];
});
return instance;
}
2.MRC下的單例需要注意什么
因為 單例對象 是用static標記過的,因此存放在 靜態(tài)區(qū).所以在MRC中 不需要 由程序員 去管理,因此要去覆蓋一些 內(nèi)存 管理的方法.
實現(xiàn)部分與ARC一致,只需要 覆蓋 一些MRC中 內(nèi)存 管理 的方法:
* - ?(id)retain .單例中不需要增加引用計數(shù)器. return self.
* - (id)autorelease .只有堆中的對象才需要.單例中不需要.return self.
* - (NSUInteger)retainCount . (可寫可不寫,防止引起誤解).單例中不需要修改引用計數(shù)延旧,返回最大的無符號整數(shù)即可.return UINT_MAX;
*- (oneway void)release .不需要release.直接覆蓋,聲明也不做.
單例模式(ARC)與(MRC)
http://www.mamicode.com/info-detail-364051.html
i??????