iPhone开发笔记[9/50]:NSMutableArray中的自动释放对象让我郁闷了一整天

news/2024/7/20 15:42:07 标签: 内存管理, 移动开发

在做一个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对象的内容就找不到了。

-------------------------------------------------------------------------------------------------------------

 

作者:毒龙的程序人生{speeding} (http://www.cnblogs.com/speeding/)
版权声明:本文的版权归作者和博客园共有,转载时须注明本文的详细链接,否则作者将保留追究其法律责任。

转载于:https://www.cnblogs.com/speeding/archive/2011/07/13/NSMutableArray-auto-free-object.html


http://www.niftyadmin.cn/n/793112.html

相关文章

python队列queue不堵塞_python 队列(queue)阻塞

背景:python 队列 queue.Queue 或 multiprcessing.Queue 或其他队列在写入队列或从队列中读取元素时,都有可能会发生线程阻塞。下面来说一下阻塞的类型,然后怎么避免阻塞~一、阻塞的类型队列的阻塞分为:入队(put)时的阻塞、出队(g…

使用倍增算法(Prefix Doubling)构造后缀数组

如果采用对每个后缀排序的方法来生成后缀数组,即使采用快速排序,由于每次比较的对象是字符串(设输入字符串的长度为n),因此每一个比较操作的复杂度不 再是常数,而是O(n),快速排序本身的平均情况…

01背包问题代码整理

以下是我收集并整理的 "01背包问题" 的c代码&#xff0c;已经在Dev-C中通过编译。 // bei_bao_01.cpp #include <stdio.h> #include <stdlib.h> /* 背包问题 01背包: 有N件物品和一个重量为M的背包。&#xff08;每种物品均只有一件&#xff09;第…

python tornado_Python Tornado篇

Tornado既是一个web server&#xff0c;也是web framework。而它作为web server 采用的是asynchronous IO的网络模型&#xff0c;这是一种很高效的模型。Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别&#xff1a;它是非阻塞式服务器&#xff…

MFC之暴力破解

原文链接&#xff1a;http://user.qzone.qq.com/386520874/blog/1389369892 随意篡改别人的代码&#xff0c;是一种不道德的行为&#xff0c;不过Hacker是个例外。---------------过客很久很久以前&#xff0c;看到同事在用simcap.exe这个软件&#xff0c;但是只是一个Demo版…

ios中的字数统计

应用做到要发新浪微博了&#xff0c;至于SDK和微博认证&#xff0c;发微博等另外再写贴&#xff0c;现在小记一下字数统计&#xff0c;因为发微博的时候只能有140个字&#xff0c;所以要用到的。 - (int)sinaCountWord:(NSString*)s {int i,n[s length],l0,a0,b0;unichar c;for…

.NET Framework 3.5 sp1离线安装方案

.net Framework 3.5 Service pack 1(Full Package) 231MB是网络上最完整的离线安装包&#xff0c;安装时却还提示要联网下载&#xff0c;如果没联网就麻烦了&#xff0c;这里下载的是语言包。这里教你自己动手制作真正的.net Framework 3.5 Service pack 1完整离线安装包. 第一…

python neo4j_py2neo——Neo4jpython的配合使用

概要之前在CSDN上写过一个blog(http://blog.csdn.net/wrzcy/article/details/51905977 )&#xff0c;简单的介绍了Neo4j图形数据库&#xff0c;主要是以基础概念和定义为主。今天就通过python面向Neo4j的库py2neo来对Neo4j进行一些简单的操作&#xff0c;包括&#xff1a;连接N…