NSMutableArray中的自動釋放對象讓我鬱悶了一整天

 

在做一個TableView程序時,要在表格裏顯示一個文件夾內所有文件的清單,程序在一開始顯示時正常,但是一滾動窗口時就崩潰,查找這個錯誤整整花了我一天的時間,原來出在NSMutableArray初始化時用的方法不正確,都是因爲Objective-C的基礎知識沒學好。

在一個UITableViewController類中聲明瞭一個NSMutableArray *localFiles這樣一個數組,作爲成員變量。

在viewDidLoad方法中讀出應用程序Documents目錄下的所有文件名放在這個數組中,初始化時用了這個方法:

localFiles = [NSMutableArray array];    //這是自動釋放的對象

然後循環調用了addObject方法,其它就沒有什麼特殊的操作了,程序能夠顯示出一個文件列表,但向上或向下滾動一點點時,程序就崩潰,顯示的錯誤信息也相當奇怪:

[__NSArrayI addObject:]: unrecognized selector sent to instance 0x4b1b8b0

我查啊查啊,每次出錯的調用棧都顯示在執行到cellForRowAtIndexPath這個方法時出錯,跟蹤到localFiles這個變量時,在調試器上顯示out of scope,這個localFiles指針裏的內容不知道跑到哪裏去了。

從google上查了許多資料,在這個網站的留言中查到下面一段話,頓時茅塞頓開:

It doesn't really matter. [NSMutableArray array] is a nice shortcut, but you have to remember to retain it, so the question really is a matter of [[NSMutableArray array] retain] versus [[NSMutableArray alloc] init]. I usually use the former. The real convenience comes in when you need to statically fill the array; you can do it all in one message. [[NSMutableArray arrayWithObjects:...] retain] is faster than [[NSMutableArray alloc] init] followed by numerous [NSMutableArray addObject:(id)] calls.

原來在調用array方法後得retain!或者改用[[NSMutableArray alloc] init]方法組合,試了2種修改辦法果然都好用,程序再也不崩潰了。就這麼幾個字,害了我幾乎一整天。

localFiles = [[NSMutableArray array] retain];

這一天裏惡補了一些Objective-C中的內存管理知識,雖然走了一些彎路,但對AutoRelease這個術語算是有了一些認識了。

後來仔細看了《Objective C教程》的第9章“內存管理”,原來第9.3節“Cocoa內存管理規則”(第138頁)裏作者早就強調三條規則:

(1)當你使用new、alloc或copy方法創建一個對象時,該對象的引用計數器值爲1。當不再使用該對象時,你要負責向該對象發送一條release或autorelease消息。這樣,該對象將在其使用壽命結束時被銷燬。

(2)當你通過任何其它方法獲得一個對象時,則假設該對象的引用計數器值爲1,而且已經被設置爲自動釋放,你不需要執行任何操作來確保該對象被清理。如果你打算在一段時間內擁有該對象,則需要保留(retain)它並確保在操作完成時釋放它。

(3)如果你保留(retain)了某個對象,你需要(最終)釋放或自動釋放該對象。必須保持retain方法和release方法的使用次數相等。

我的程序是iPhone程序,爲了降低程序的內存空間佔用,Cocoa在GUI應用程序中規定了自動釋放池的銷燬時間,在程序開始處理事件之前創建一個自動釋放池,並在事件處理結束後銷燬該自動釋放池。我的localFiles對象在開始時創建了一個自動釋放對象,完成之後進行下一個事件循環,自動釋放池已經銷燬,localFiles對象也就被釋放了,在滾動tableView時進入下一個事件循環,所以localFiles對象的內容就找不到了。

http://www.cnblogs.com/speeding/archive/2011/07/13/2105309.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章