在做一个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对象的内容就找不到了。
分享到:
相关推荐
Objective-C的数组比C++,Java的数组强大在于,NSArray保存的对象可以是不同的对象。但只能保存对象,int ,char,double等基本数据类型不能直接保存,需要通过转换成对象才能加入数组。
NSMutableArray-SafeTransaction NSMutableArray线程安全事务 NSMutableArray不是线程安全的,如果您向每个API添加锁定,则会被包围。... 线程#2删除最后一个对象。 线程#1访问count-1对象,然后引发异常。
下面小编就为大家分享一篇iOS 对NSMutableArray进行排序和过滤的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
主要介绍了IOS 开发之 NSMutableArray与NSArray 的区别的相关资料,希望通过本文能掌握这部分内容,需要的朋友可以参考下
NSMutableArray-Delegate 是为可变数组添加模式委托的类别。 支持的委托方法 - (void)mutableArray:(NSMutableArray *)array willAddObject:(id)object - (void)mutableArray:(NSMutableArray *)array didAddObject...
NSMutableArray +随机播放NSMutableArray上的一个有用的类别,提供了一种重新排列数组的方法。用法在要添加随机播放功能的类中导入NSMutableArray + Shuffle.h文件。 # import " NSMutableArray+Shuffle.h " 创建...
Iphone数组一些基础操作 NSArray/NSMutableArrayIphone
仿网易自动循环广告 也可手动滑动 可自定义自动滚动时间间隔 这个例子是从其他地方下的 不过原始代码里存在严重的内容泄露 使用时间长了 会发现滚动缓慢 这个bug 已被我修复 使用方法如下: NSMutableArray ...
在实际的项目中,IPhone应用程序会存在很多与服务器之间的数据交互的地方,XML是首选方案。 此包可以解决XML文件的解析、对象转化为XML字符串的问题。 1 通过调用解析类,可以将XML的DATA数据转换为XmlNode对象,...
数组是线性结构是容器类型,是一块连续的内存空间, iOS 中用 NSArray 和 NSMutableArray 集合类型,用来存放对象类型,其中 NSArray是不可变类型, NSMutableArray 是可变类型,能够对数组中元素进行增删改查. ...
功能安全访问NSArray安全访问NSDictionary安全访问并对NSMutableArray进行更改安全访问并对NSMutableDictionary进行更改安全访问并对NSMutableString进行更改要求iOS 8.0+ / macOS 10.13.6+ Xcode 10.1(10B61)+...
专业的数据库存储解决方案,线程安全,高性能模型对象存储Sqlite开源库,真正实现一行代码操作数据库,让数据库存储变得简单 简介 架构:采用运行时和SQLite完美结合打造的强大数据库操作引擎开源库 安全:支持...
NSMutableArray *list = [[NSMutableArray alloc]init]; NSMutableDictionary *map1 = [[NSMutableDictionary alloc]init]; [map1 setObject:@"a1" forKey:@"author"]; [map1 setObject:@"b1" forKey:@"title"];...
NSValue 可以弱引用保存一个对象,我们可以使用这种方法间接的引用。 NSValue *value = [NSValue valueWithNonretainedObject:@selector(class)]; [array addObject:value]; 2. 使用 NSPointerArray,NSMapTable,...
OCGeneric Objective-C的基础通用支持。 包括OCGenerics.h ...当您要将NSNumber对象添加到NSString数组中时,Xcode将找出错误的类型 扩展名 您可以基于此进行扩展,方法是在OCGenerics.h中添加更
OCMockito是Mockito的Objective-C实现,支持模拟对象的创建,验证和存根。 与其他模拟框架的主要区别: 模拟对象始终是“不错的”,记录它们的调用,而不是抛出未指定调用的异常。 这使得测试不那么脆弱。 没有...
我写的是一篇 UITableViewCell使用自动布局的“最佳实践” ,我需要给我的图片里面的UIView元素添加上边距的标记,这让我感到很为难,我觉得我得发点时间写一个程序让这个步骤自动化,我只要一键就能让我的程序自动...
//判断两个字符串是否相等,不能使用==,使用等号是判断两个对象是否是一个对象,也就是是否是一个内存地址。 //判断字符串的内容是否相同应该使用nsstring的isEqualToString:方法 //在低版本的时候,如果直接点击...
Linq2NSObjects 从 .net 框架切换到 ... 我们能够找到的类似库通常将对象从一个数组转换为另一个数组并返回它。 例如: - ( NSArray *)select:(Selector)selector { NSMutableArray * result = [[ NSMutable
NSMutableArray *array = [NSMutableArray array]; // 1.2循环生成图片名,根据图片名把图片存入数组 for (int i = 0; i < frames; i ) { NSString *string = [NSString stringWithFormat:@"eat_d", i]; /...