objc中,與alloc語義相反的方法是dealloc還是release堰氓?與retain語義相反的方法是dealloc還是
release塔沃,為什么礁遵?需要與alloc配對使用的方法是dealloc還是release脱惰,為什么?
答:alloc與dealloc語意相反窿春,alloc是創(chuàng)建變量拉一,dealloc是釋放變量采盒。retain對應(yīng)release,retain保留一個對象。調(diào)用之后蔚润,變量的計數(shù)加1磅氨。或許不是很明顯嫡纠,在這有例為證:
- (void) setname : (nsstring*) name {
[name retain];
[myname release];
myname = name;
}我們來解釋一下:設(shè)想烦租,用戶在調(diào)用這個函數(shù)的時候,他注意了內(nèi)存的管理除盏,所以他小心的寫了如下代碼:
nsstring * newname = [[nsstring alloc] initwithstring:@"john"];
[aclass setname: newname];
[newname release];
我們來看一看newname的計數(shù)是怎么變化的叉橱。首先,它被 alloc者蠕,count = 1;然后窃祝,在setname中,它被retain踱侣,count = 2; 最后粪小,用戶自己釋放newname,count=1抡句,myname指向了newname探膊。這也解釋了為什么需要調(diào)用[mynamerelease]。我們需要在給myname賦新值的時候待榔,釋放掉以前老的變量逞壁。retain之后直接dealloc對象計數(shù)器沒有釋放。alloc需要與release配對使用究抓,因?yàn)閍lloc這個函數(shù)調(diào)用之后猾担,變量的計數(shù)加1。所以在調(diào)用alloc之后刺下,一定要調(diào)用對應(yīng)的release绑嘹。另外,在release一個變量之后橘茉,他的值仍然有效工腋,所以最好是后面緊接著再var= nil。
在一個對象的方法里面:self.name = “object”;和name =”object”有什么不同嗎?
答:self.name = "object"會調(diào)用對象的setname()方法畅卓,name ="object"會直接把object賦值給當(dāng)前對象的name 屬性擅腰。
這段代碼有什么問題嗎:
@implementation person
- (void)setage:(int)newage {
self.age = newage;
}
@end
答:會進(jìn)入死循環(huán)。
什么是retain count?
答:引用計數(shù)(ref count或者retaincount)翁潘。對象的內(nèi)部保存一個數(shù)字趁冈,表示被引用的次數(shù)。例如,某個對象被兩個指針?biāo)赶颍ㄒ茫┠敲此膔etaincount為2需要銷毀對 象的時候渗勘,不直接調(diào)用dealloc沐绒,而是調(diào)用release。release會 讓retaincount減1旺坠,只有retain count等于0乔遮,系統(tǒng)才會調(diào)用dealloc真正銷毀這個對象。
以下每行代碼執(zhí)行后取刃,person對象的retain count分別是多少蹋肮?
person *person = [[person alloc] init];
count 1[person retain];
count 2[person release];
count 1[person release];
retain count = 1;
為什么很多內(nèi)置類如uitableviewcontroller的delegate屬性都是assign而不是retain的?
答:會引起循環(huán)引用 所有的引用計數(shù)系統(tǒng)璧疗,都存在循環(huán)應(yīng)用的問題坯辩。例如下面的引用關(guān)系:
對象a創(chuàng)建并引用到了對象b.
對象b創(chuàng)建并引用到了對象c.
對象c創(chuàng)建并引用到了對象b.
這時候b和c的引用計數(shù)分別是2和1。當(dāng)a不再使用b病毡,調(diào)用release釋放對b的所有權(quán)濒翻,因?yàn)閏還引用了b,所以b的引用計數(shù)為1啦膜,b不會被釋放有送。b不釋放,c的引用計數(shù)就是1僧家,c也不會被釋放雀摘。從此,b和c永遠(yuǎn)留在內(nèi)存中八拱。
這種情況阵赠,必須打斷循環(huán)引用,通過其他規(guī)則來維護(hù)引用關(guān)系肌稻。我們常見的delegate往往是assign方式的屬性而不是retain方式的屬性清蚀,賦值不會增加引用計數(shù),就是為了防止delegation兩端產(chǎn)生不必要的循環(huán)引用爹谭。如果一個uitableviewcontroller對象a通過retain獲取了uitableview對象b的所有權(quán)枷邪,這個uitableview對象b的delegate又是a,如果這個delegate是retain方式的诺凡,那基本上就沒有機(jī)會釋放這兩個對象了东揣。自己在設(shè)計使用delegate模式時,也要注意這點(diǎn)腹泌。
定義屬性時嘶卧,什么情況使用copy,assign凉袱,和retain 芥吟。
答:assign用于簡單數(shù)據(jù)類型,如nsinteger,double,bool,retain 和copy用戶對象,copy用于當(dāng)a指向一個對象运沦,b也想指向同樣的對象的時候泵额,如果用assign酷含,a如果釋放庵芭,再調(diào)用b會crash,如果用copy的方式袍睡,a和b各自有自己的內(nèi)存,就可以解決這個問題烈掠。retain會使計數(shù)器加一,也可以解決assign的問題缸托。另外:atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作左敌。在多線程環(huán)境下,原子操作是必要的俐镐,否則有可能引起錯誤的結(jié)果矫限。加了atomic,setter函數(shù)會變成下面這樣:
if(property!=newvalue){
[propertyrelease];
property=[newvalueretain];
}
autorelease的對象是在什么時候被release的佩抹?
答:autorelease實(shí)際上只是把對release的調(diào)用延遲了叼风,對于每一個autorelease,系統(tǒng)只是把該object放入了當(dāng)前的autoreleasepool中棍苹,當(dāng)該pool被釋放時无宿,該pool中的所有object會被調(diào)用release。對 于每一個runloop枢里,系統(tǒng)會隱式創(chuàng)建一個autorelease pool孽鸡,這樣所有的releasepool會構(gòu)成一個象callstack一樣的一個棧式結(jié)構(gòu),在每一個runloop結(jié)束時栏豺,當(dāng)前棧頂?shù)腶utoreleasepool會被銷毀彬碱,這樣這個pool里的每個object(就是autorelease的對象)會被release。那什么是一個runloop呢奥洼?一個ui事件巷疼,timer call, delegate call溉卓, 都會是一個新的runloop皮迟。那什么是一個runloop呢?一個ui事件桑寨,timer call伏尼, delegate call, 都會是一個新的runloop尉尾。
這段代碼有什么問題,如何修改
for (int i = 0; i < somelargenumber; i++){
nsstring *string = @”abc”;
string = [string lowercasestring];
string = [string stringbyappendingstring:@"xyz"];
nslog(@“%@”, string);
}
答:會內(nèi)存泄露爆阶,
for(inti =0;i<1000;i++)
{ nsautoreleasepool* pool1 =[[nsautoreleasepoolalloc]init];
nsstring*string =@"abc";
string = [stringlowercasestring];
string =[stringstringbyappendingstring:@"xyz"];
nslog(@"%@",string);
[pool1drain];
}
什么是notification?
答:觀察者模式,controller向defaultnotificationcenter添加自己的notification辨图,其他類注冊這個notification就可以收到通知班套,這些類可以在收到通知時做自己的操作(多觀察者默認(rèn)隨機(jī)順序發(fā)通知給觀察者們,而且每個觀察者都要等當(dāng)前的某個觀察者的操作做完才能輪到他來操作故河,可以用notificationqueue的方式安排觀察者的反應(yīng)順序吱韭,也可以在添加觀察者中設(shè)定反映時間,取消觀察需要在viewdidunload 跟dealloc中都要注銷)鱼的。
什么時候用delegate理盆,什么時候用notification?
答:delegate針對one-to-one關(guān)系凑阶,并且reciever可 以返回值給sender猿规,notification可以針對one-to-one/many/none,reciever無法返回值給sender.所以,delegate用于sender希望接受到reciever的某個功能反饋值宙橱,notification用于通知多個object某個事件姨俩。
什么是kvc和kvo?
答:kvc(key-value-coding)內(nèi)部的實(shí)現(xiàn):一個對象在調(diào)用setvalue的時候师郑,(1)首先根據(jù)方法名找到運(yùn)行方法的時候所需要的環(huán)境參數(shù)环葵。(2)他會從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口呕乎。(3)再直接查找得來的具體的方法實(shí)現(xiàn)积担。kvo(key-value-observing):當(dāng)觀察者為一個對象的屬性進(jìn)行了注冊,被觀察對象的isa指針被修改的時候猬仁,isa指針就會指向一個中間類帝璧,而不是真實(shí)的類。所以isa指針其實(shí)不需要指向?qū)嵗龑ο笳鎸?shí)的類湿刽。所以我們的程序最好不要依賴于isa指針的烁。在調(diào)用類的方法的時候,最好要明確對象實(shí)例的類名诈闺。
ViewController 的 loadView, viewDidLoad, viewDidUnload
分別是在什么時候調(diào)用的渴庆?在自定義ViewController的時候這幾個函數(shù)里面應(yīng)該做什么工作?
答:viewDidLoad在view從nib文件初始化時調(diào)用雅镊,loadView在controller的view為nil時調(diào)用襟雷。此方法在編程實(shí)現(xiàn)view時調(diào)用,view控制器默認(rèn)會注冊memory warning notification,當(dāng)view controller的任何view沒有用的時候,viewDidUnload會被調(diào)用仁烹,在這里實(shí)現(xiàn)將retain 的viewrelease,如果是retain的IBOutlet view 屬性則不要在這里release,IBOutlet會負(fù)責(zé)release耸弄。
自動釋放池是什么,如何工作?
當(dāng)您向一個對象發(fā)送一個autorelease消息時卓缰,Cocoa就會將該對象的一個引用放入到最新的自動釋放池计呈。它仍然是個正當(dāng)?shù)膶ο笈樗校虼俗詣俞尫懦囟x的作用域內(nèi)的其它對象可以向它發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時捌显,自動釋放池就會被釋放茁彭,池中的所有對象也就被釋放。
1.ojc-c 是通過一種"referringcounting"(引用計數(shù))的方式來管理內(nèi)存的,對象在開始分配內(nèi)存(alloc)的時候引用計數(shù)為一,以后每當(dāng)碰到有copy,retain的時候引用計數(shù)都會加一,每當(dāng)碰到release和autorelease的時候引用計數(shù)就會減一,如果此對象的計數(shù)變?yōu)榱?, 就會被系統(tǒng)銷毀.2.NSAutoreleasePool 就是用來做引用計數(shù)的管理工作的,這個東西一般不用你管的.3.autorelease和release沒什么區(qū)別,只是引用計數(shù)減一的時機(jī)不同而已,autorelease會在對象的使用真正結(jié)束的時候才做引用計數(shù)減一.