NSMutableArray初始化崩溃问题

现象:

@property(nonatomic, copy) NSMutableArray *array;

self.array = [NSMutableArray alloc] initWithCapacipty:5];

[self.array addObject:@"hello"];

//大师们为什么上面这样写会报错啊

//如果像下面这样写就不报错了,这是为什么呀

_array = [[NSMutableArray alloc] initWithCapacipty:5];

[_array addObject:@"hello"];

楼主还没弄透@property(我自己也是一知半解),你用self.array = 是通过setter方法来给array赋值,而你又给这个setter方法设置copy,而经过copy生成的array指针指向的是一个不可变数组

(详细请参见苹果的官方文档),这时你在调用add方法,肯定会出问题,而且Xcode会提示:“unrecognized selector sent to instance” 。 

至于_array为什么不报错,很简单,因为_array 是一个变量,没有copy修饰,指向的还是你原来生成的可变数组,所以add方法有效。

现象2:

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

时间: 2024-07-30 15:44:16

NSMutableArray初始化崩溃问题的相关文章

NSArray NSMutableArray 初始化

NSArray* Array;//此时数组没有初始化,数组=nil [Array objectAtIndex:2];//不会调用其属性方法,这里不会崩溃 NSMutableArray *MutableArray=[[NSMutableArray alloc]init];//此时数组被初始化,数组 !=nil 有0个object [MutableArray firstObject];//会调用其属性方法,不会崩溃 [MutableArray objectAtIndex:0];//会调用其属性方法,

MySQL · 引擎特性 · InnoDB 崩溃恢复过程

MySQL · 引擎特性 · InnoDB 崩溃恢复过程 在前面两期月报中,我们详细介绍了 InnoDB redo log 和 undo log 的相关知识,本文将介绍 InnoDB 在崩溃恢复时的主要流程. 本文代码分析基于 MySQL 5.7.7-RC 版本,函数入口为 innobase_start_or_create_for_mysql,这是一个非常冗长的函数,本文只涉及和崩溃恢复相关的代码. 在阅读本文前,强烈建议翻阅我们之前的两期月报:1. MySQL · 引擎特性 · InnoDB

[UIApplication]简介

The UIApplication class provides a centralized point of control and coordination for apps running on iOS. Every app must have exactly one instance of UIApplication (or a subclass of UIApplication). When an app is launched, the UIApplicationMain funct

第九章 竞品技术分析

开机速度 splash广告逻辑,首次加载的图片为应用放在res文件夹下面几个文件夹里面的图片,同时会去调用接口获取下一次打开的时候要显示的图片url,并缓存图片:下次进入该界面显示图片并继续访问接下来一次的图片,为了保证打开速度,这个网络请求务必异步处理. 引导图,不要超过4页.动画可原生实现,可gif,可视频来实现. 进入首页之前进行地理位置的定位,保证进入首页显示的数据为当前城市的信息. app首页设计,尽可能多的将所有产品展示在首页,会有广告,搜索栏,滚动条. 上面为用户可见的数据,一些不

ios 集合总结

NSArray 用于对象有序集合(相当于是数组) NSSet 用于对象无序集合 NSDictionary 用于键值映射 以上三种集合类是不可变的(一旦初始化后,不能再动态的增加或删除元素),如果需要用到可变集合,则需要用到下面几个类: NSMutableArray NSMutableSet NSMutableDictionary 实例DEMO: 1:NSArray 初始化和遍历迭代 (1)NSArray的初始化 NSArray的便利初始化函数: -(id) initWithObjects : (

防止忘记初始化NSMutableArray的方法

在写项目的过程中,经常会遇到一些郁闷的事,往一个可变数组中添加一个模型数据时,经常会发现程序运行很正常,可是可变数组中就是没有任何数据,久病成医,我发现自己总是放一个错,就是NSMutableArray没有初始化,接着就郁闷了…… 今天看到一个比较好的写法,可以有效地防止这种低级错误地发生: .h文件 @interface ModalCenter:NSObject @property (nonatomic,retain) NSMutableArray * dogArray; @end .m文件

NSmutableArray添加数据添加失败打印NULL - 没有初始化/初始化写错

今天犯了一个小错误  -> 可变数组添加解析出来的模型, 添加不了.在下了断点测试,forin里打印数组一直NULL. 弄了我两个多小时还是没有解决. 在检查代码过程中 发现懒加载方法的命名打错了.导致没有初始化.在此记录下自己的小错误. 1 /** 数据数组 */ 2 3 @property (nonatomic, strong) NSMutableArray *statuses; 4 5 6 7 //更改前 8 9 - (NSMutableArray *)status{ 10 11 if (

【有意思的BUG】客户端无厘头 已连网的场景初始化太慢 未连网的场景异常崩溃

客户端 已连网的场景初始化太慢 当在未连接internet的时候,打开某些APP,会比较迅速地初始化进入到主页面. 但是当我在已经连接了internet的时候,打开某些APP,有些会初始化很久!!!! 举例1: 已经连接了internet的时候,打开网易有道词典. 这时候,客户端从“网易有道词典封面页”跳转到“搜词页”,此时尝试触屏去点击搜索输入框区域是无效的,因为页面正在等待服务器的响应,这个等待时间太久了,短则5-10秒,长则20秒. 不知道设计者有没有考虑“英文词典”这类软件的使用场景?当

单例初始化(MRC模式之autorelease)

最近在一项目中,在某个地方总是有内存闪退问题,经排查之后,终于找到问题所在. 项目中崩溃的地方使用单例写的(MRC模式),其中单例的初始化方法如下: + (GetCalendarEvents *)shareInstence { if (_get == nil) { _get = [[[GetCalendarEvents alloc] init] autorelease]; _get.projectPlanArray = [[[NSMutableArray alloc] init] autorel