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