最近安卓APP開(kāi)發(fā),IOSAPP開(kāi)發(fā)公司有很多,但是IOS仍然會(huì)存在很多問(wèn)題,下面小編主要為APP開(kāi)發(fā)者講解5個(gè)點(diǎn):
(1)任何一個(gè)UIView如果沒(méi)有被remove掉,即使它被release掉了,依然占用著大量?jī)?nèi)存。UIView需要remove,數(shù)組需要清空;對(duì)于一個(gè)擁有大量subView的UIView,要最好使用一個(gè)for循環(huán)來(lái)執(zhí)remove操作
?。?)隱藏內(nèi)存泄漏,比如一個(gè)UIView,fatherView,上面有許多的子視圖,如果有釋放內(nèi)存的時(shí)候僅僅釋放fatherView的內(nèi)存(對(duì)其執(zhí)行remove,release操作),那么此處必定內(nèi)存無(wú)法回收。即使你的subviews已經(jīng)release了,retainCount=0,但是并沒(méi)有remove,所以這也是內(nèi)存泄漏。
?。?)下面說(shuō)說(shuō)alloc、retain、copy,見(jiàn)到這三個(gè)不用說(shuō)必須release。alloc和retain都會(huì)造成計(jì)數(shù)器
ClassA *obj1 = [[ClassA alloc] init];// obj1的計(jì)數(shù)器加
ClassA *obj2=obj1; // obj1的計(jì)數(shù)器再次加1為
[obj2 retain]; // 這樣寫計(jì)數(shù)器加1為
[obj1 release]; // obj1的計(jì)數(shù)器減1為
[obj2 release]; // 這里也可以寫成[obj1 release] ,基于誰(shuí)retain誰(shuí)釋放原則最好不這么寫
說(shuō)下copy深拷貝和retain淺拷貝的區(qū)別
ClassA *obj1 = [[ClassA alloc] init]; // obj1計(jì)數(shù)器j加
ClassA *obj2 = [obj1 copy] // obj1計(jì)數(shù)器不加1,obj2計(jì)數(shù)器加
[obj1 release] // obj2計(jì)數(shù)器為0,釋放時(shí)必須這樣寫了
[obj2 release] // obj1計(jì)數(shù)器為
如上,這里注意釋放對(duì)象及釋放順序
?。?)關(guān)于屬性聲明,首先說(shuō)說(shuō)
@property:你可以理解為系統(tǒng)給你寫了get/set方法
-(void) setName:(NSString *)name{ if (_name != name) { [_name release]; _name = [name retain];//這行就是下面解釋的屬性中你定義的屬性起到的作用
readonly屬性: 只能讀,不能寫;
assign屬性: 是默認(rèn)屬性,直接賦值,沒(méi)有任何保留與釋放問(wèn)題;
retain屬性: 會(huì)增加原有對(duì)象的引用計(jì)數(shù)并且在賦值前會(huì)釋放原有對(duì)象,然后在進(jìn)行賦值;
copy屬性: 會(huì)復(fù)制原有對(duì)象,并在賦值前釋放原有對(duì)象,然后在進(jìn)行賦值;
atomic、assign、readwrite這三種屬性是默認(rèn)的,可不寫,基本上所有@property都是noatomic的,也就是非線程安全的
除了基本類型和delegate用assign,其他都用retain,有因?yàn)閍ssign是默認(rèn)屬性,所以類似
可以直接寫成
說(shuō)道屬性順便說(shuō)下self.屬性 = 值,self set屬性 = 值,屬性 = 值,這三種賦值的區(qū)別
第一種和第二種方式都會(huì)造成計(jì)數(shù)器加1,需要release掉,而第三種直接賦值給屬性可以稱為弱引用沒(méi)有計(jì)數(shù)器加1。如果釋放掉后會(huì)造成n內(nèi)存釋放過(guò)度。
?。?)[(UIButton *)[self.view viewWithTag:123] removeFromSuperview]和[[self.view viewWithTag:123] removeFromSuperview]效果是不一樣的,通過(guò)tag取出來(lái)的對(duì)象需要類型轉(zhuǎn)換才能正確移除掉