日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IOS内存管理2

發布時間:2023/12/31 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IOS内存管理2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ??很多童鞋對于IOS中的內存管理處理的不好,有時候感覺自己已經掌握了,其實用起來的時候往往出現很多的內存泄露或者因為內存管理的不恰當導致程序崩潰!
網上有一片很詳細的內存管理文章,很多人估計嫌長,不愿意去看,我就寫一個簡單易懂的分享。
我分四塊來講解,這篇文章比較簡單,因為我不想把你們搞暈,其實總的來說就一個原則!
一、IOS內存管理的機制
IOS中沒有垃圾回收機制(IOS5中好像已經有了,但是目前還不太實用),所以基本一切都是自己手動管理。
IOS中采用引用計數的內存管理方式,啥意思呢?講的通俗點就是說一塊內存地址是否應該被釋放是又retaincount來決定的,如果這塊內存地址的retaincount為0,那么這塊內存就會被釋放,再也找不到了。
所以想讓他一直存在,那么它的retaincount就必須大于0。
那么如何管理呢?其實原理非常簡單,就是誰用誰retain,誰retain的誰release,遵循這個原則的目的就是讓你不會出錯。
舉個例子
? ClassA *obj1 = [[ClassA alloc] init];?

這里你申請了一塊內存地址,指針obj1指向了這塊內存地址,同時你給它retain了一下(retain,copy,alloc這幾個方法都相當于把retaincount加一),此時obj1所指向的這塊內存地址retaincount為1。
接著來(這里我只是舉例子讓大家了解一下,這些代碼沒有什么實際意義)
ClassA *obj2=obj1;
[obj2 retain]; ? 好了,大家看一下,obj1和obj2同時都指向了上面所述的內存地址,我假設這塊內存為A,那么A這塊內存的retaincount為2。
假如大家在之后一直在使用obj1和obj2,最后不用的時候,需要釋放了,我希望大家這樣來釋放
? [obj1 release];
[obj2 release];
? 而不希望大家這樣來釋放
[obj1 release];
[obj1 release];
//或者
[obj2 release];
[obj2 release]; ? 為什么這樣呢?上面兩種釋放方法沒有錯,都成功將A這塊內存的retaincount減為0,導致A被釋放了。但是你沒有遵循以上所說“誰用誰retain,誰retain的誰release”。
這只是一個小例子,你可能感覺不到問題的嚴重性,如果你做一個項目,在其中有大量這種retain,release的話,你不遵循這種原則,你會死的很慘,沒有條理最后你會被搞的很亂,找都找不到。
二、不要隨便看到retaincount多就給它釋放
很多朋友在學完內存管理后喜歡玩消除,不該釋放的他去釋放,舉個例子
? UIViewController *ct1=[[UIViewController alloc] init];[self.navigationcontroller pushViewController:ct1 animated:YES];[ct1 relese];
? 這里,初始化一個viewcontroller,然后用導航push進來,最后釋放這個viewcontroller,很多人在這里操作完畢后,繼續打印ct1的retaincount,發現它的retaincount不為0,就繼續release,這里是非常錯誤的方法,直接導致程序崩潰,繼續看以上原則“誰用誰retain,誰retain的誰release”,你用的時候,初始化,并retain了一次,最后你release了一次,到此結束!之后不管你發現它的retaincount為幾,你都不該再release。你打印出來的retaincount并不是你retain的,而是系統框架本身retain的,由框架本身來處理,開發者不必理會。
類似還有很多,數組的addobject、addsubview等等很多方法,都是框架自己家retain的,開發者本身retain后release,不必理會它的retaincount。
另外插一句,如果是多人協同開發,這種情況最容易碰到,別人傳遞一個參數過來,你拿過來retain后使用,使用完畢release,發現retaincount還不是0,于是你繼續release,這樣你就把你同伴retain的計數給release掉了,當他下次使用的時候發現崩潰了,這種情況會讓你的團隊浪費無數的時間來找原因。
? 三、關于屬性
屬性在.h文件中是這樣聲明的
? @property(nonatomic,retain) Class *obj;
? 括號內第二個參數代表的意義是什么呢?
我們分析一下他內部的機制
@property (retain) Class* obj;@synthesize obj;實際上是gettersetter,有retain參數的property,內部代碼如下
? -(Class *) getObj
{
? ? ? ? ?return obj;
}


-(void) setObj:(Class *) value
{
? ? ? ? ?if (obj != value)
? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?[obj release];
? ? ? ? ? ? ? ? ? ?obj = [value retain];
? ? ? ? ?}
}

愿意仔細分析的童鞋可以仔細研究一下,不太明朗的童鞋請聽我說。
這個屬性定義以后如何使用呢?我們只說賦值(也就是set)
self.obj=xxx;
[self setObj:xxx];
obj=xxx;
賦值方法有以下幾種,其中前兩個是相同的,都是調用了setObj:方法同時也就導致了obj的retaincount增加了1,而第三個賦值方法并沒有增加retaincount,只是將指針指向了xxx內存地址。
所以大家賦值時可以這樣
Class *c=[[Class alloc] init]; self.obj=c;[c release];
或者Class *c=[[Class alloc] init];
[self setObj:c];[c release]; 或者Class *c=[[Class alloc] init];obj=c;
? 屬性的這個機制是讓你在整個self里(也就是當前類的實例里)一直保留這個obj的retaincount,所以你必須在此類的dealloc里將obj的retaincount置零(你只需要release,如果你嚴格遵守“誰用誰retain,誰retain的誰release”的話)
-(void)dealloc
{
? ? [obj release];
? ? [super dealloc];
} ? ? 這里,其實我主要要說明的就是屬性的賦值方式用self.xxx=xxxx和xxx=xxxx是完全不同的賦值方式,大家切記!
四、autorelease對象
autorelease對象就是自動釋放對象,大家可能會疑惑,能自動釋放,我還管理干嘛,我都用自動釋放算了,事實不是這樣的,自動釋放確實好用,但是自己管理內存才能讓項目占用更小的資源,跑起來更流暢,大家可以手動管理加autorelease一起來使用,我先講解一下autorelease對象到底是什么個情況。
首先,告訴大家autorelease對象什么時候才會被釋放。
在main函數里有一個autorelease pool,自動釋放池,所以在這個自動釋放池里的autorelease對象都會在自動釋放池結束的時候全部被釋放。
大家可能會問了,“難道所有的autorelease對象都是在程序退出的時候才被釋放?”,答案當然不是,其實main函數中只是一個程序中眾多自動釋放池中的一個,每個runloop都會隱性的創建一個自動釋放池,啥是一個runloop?每個UIView創建、delegate回調等等都會創建一個自動釋放池,記得這個“等等”,意思就是有很多(如果大家想要詳細了解runloop,可以去google)。所以大家不用擔心autorelease對象不會被釋放。
很多系統的方法,比如[NSArray array]、[NSString stringformat]等等返回的對象都是autorelease對象,這些對象是不需要手動釋放的,如果手動釋放會導致程序崩潰!切記!,原則就是系統中所有沒有使用alloc、copy、retain來創建的對象都是autorelease對象,大家千萬別手動release!


轉:http://blog.csdn.net/tt5267621/article/details/7632004

總結

以上是生活随笔為你收集整理的IOS内存管理2的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。