我对这个小应用程序感到很疯狂......请帮助我!!!
这是该应用的源代码:Smoking.zip
它只保存带有NSMutableArray的.dat文件。 现在,您第一次启动应用程序时,有时会尝试单击香烟按钮:一切都应该正常工作。 好的,现在关闭应用程序,重新打开它,再次单击按钮。这次应用程序将崩溃,“无法识别的选择器发送到实例0x5d18d60”错误。 我确定问题在于保存数据,因为当我评论“[theData writeToFile:dataFilePath atomically:YES];”时在“saveData”方法中,错误消失了。 后来我发现如果我尝试从NSMutableArray中读取数据,它会再次出现。
请花点时间检查我的项目并帮助我,因为我为此疯狂!
答案 0 :(得分:1)
你这个疯子,花了很长时间才找到这些线:
Cig *oldCig = [mainDelegate.smokeArray lastObject];
...
[oldCig release];
你为什么这样做?您有效地将数组中最后一个对象的保留计数减少到0.保存时,可以很好地保存它,其保留计数为零。
在反序列化时,解码器将保留它解码的任何(子)元素,因此最后一个对象的保留计数将在短时间内为1.然后,在释放解码器时,它释放所有元素,poof是最后一个Cig对象。从数组中获取该对象时,会得到指向完全不同的指针,并且应用程序崩溃。
你应该阅读内存处理。 lastObject
只返回指向数组中对象的指针,而不保留它,因此您不必释放它。此外,对于像
- (NSArray *) quando
尝试返回一个自动释放的数组,在返回之前调用autorelease:
NSArray *newArray = [[[NSArray alloc] initWithObjects:year,...,nil] autorelease];
然后你的其他代码不必考虑释放它。并释放dateFormatter。您alloc
,retain
,copy
或new
的任何内容,都必须release
或autorelease
!
答案 1 :(得分:0)
容易。在SDK 3.2和4.0上,您需要使按钮功能如下。
// Note it takes one argument UIButton.
- (IBAction) smoke:(UIButton * ) button {
在您的.h文件和.m文件中更改此内容,您无需更改任何其他内容。为我工作。