Cad*_*adu 2 cocoa-touch memory-leaks objective-c nsmutablearray
我在这里遇到一个难题,不管感谢,我的意思是任何帮助=)
我是一名经验丰富的开发人员,我是Objective-C/iPhone/Cocoa的新手.
我想创建一个类控制器,我可以将NSMutableArray作为参数传递.
然后,我们有:
selTimeIntController = [[SingleSelectPickerViewController alloc] initWithSettings: listOfIntervals :kAlarmIntervalStr :myDataHolder.alarmInterval];
[self.navigationController pushViewController: selTimeIntController animated: YES];
[selTimeIntController release];
Run Code Online (Sandbox Code Playgroud)
这个listOfIntervals是一个已经是alloc/init的NSMutableArray*.
在我的SingleSelectPickerViewController上,我们有:
-(id)initWithSettings:(NSMutableArray*)sourceArray :(NSString*)viewCurrentValue :(NSString*)viewTitle {
if(self = [self initWithNibName: kNibName bundle: [NSBundle mainBundle]]) {
listOfIntervals = [NSMutableArray arrayWithArray: (NSMutableArray*)sourceArray];
currentValue = [[NSString alloc] initWithString: viewCurrentValue];
title = [[NSString alloc] initWithString: viewTitle];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
通过调试,我能够在SingleSelectPickerViewController上看到我的listOfIntervals.
这里我们有SingleSelectPickerViewController'dealloc:
- (void)dealloc {
[super dealloc];
[listOfIntervals release];
[currentValue release];
[title release];
}
Run Code Online (Sandbox Code Playgroud)
但是,每次我实例化我的SingleSelectViewController时,我都会收到一个带有以下堆栈的EXEC_BAD_ADDRESS:
#0 0x96132688 in objc_msgSend ()
#1 0x00003ee2 in -[SingleSelectPickerViewController tableView:numberOfRowsInSection:] (self=0xd38940, _cmd=0x319a6bc0, tableView=0x102e000, section=0) at /Users/Cadu/iPhone/myApp/Classes/SingleSelectPickerViewController.m:115
#2 0x30a86bb4 in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] ()
#3 0x30a8879b in -[UITableViewRowData rectForFooterInSection:] ()
#4 0x30a883c7 in -[UITableViewRowData heightForTable] ()
#5 0x3094e8e6 in -[UITableView(_UITableViewPrivate) _updateContentSize] ()
#6 0x30940a7d in -[UITableView noteNumberOfRowsChanged] ()
#7 0x3094a2a0 in -[UITableView reloadData] ()
#8 0x30947661 in -[UITableView layoutSubviews] ()
#9 0x00b41d94 in -[CALayer layoutSublayers] ()
#10 0x00b41b55 in CALayerLayoutIfNeeded ()
#11 0x00b413ae in CA::Context::commit_transaction ()
#12 0x00b41022 in CA::Transaction::commit ()
#13 0x00b492e0 in CA::Transaction::observer_callback ()
#14 0x30245c32 in __CFRunLoopDoObservers ()
#15 0x3024503f in CFRunLoopRunSpecific ()
#16 0x30244628 in CFRunLoopRunInMode ()
#17 0x32044c31 in GSEventRunModal ()
#18 0x32044cf6 in GSEventRun ()
#19 0x309021ee in UIApplicationMain ()
#20 0x000020d8 in main (argc=1, argv=0xbffff0b8) at /Users/Cadu/iPhone/MyApp/
Run Code Online (Sandbox Code Playgroud)
知道发生了什么事吗?
问题的标题是"内存泄漏".问题中的所有内容都表示"崩溃".这是一个崩溃,而不是内存泄漏.或者,至少,在修复crashers之前,你不会知道是否有内存泄漏.
最可能的崩溃源是listOfIntervals实例变量的错误管理.
listOfIntervals = [NSMutableArray arrayWithArray: (NSMutableArray*)sourceArray];
Run Code Online (Sandbox Code Playgroud)
具体来说,这需要是:
listOfIntervals = [[NSMutableArray arrayWithArray: sourceArray] retain];
Run Code Online (Sandbox Code Playgroud)
正如迈克上面指出的那样,传递一个可变的集合参考可能是一个坏主意.如果sourceArray从班级下面改变怎么办?你准备好应对吗?
一个更常见的习惯用法是将你的方法声明为采用NSArray*然后复制数组:
listOfIntervals = [sourceArray mutableCopy]; // or -copy, if you don't need it to be mutable
Run Code Online (Sandbox Code Playgroud)
(1)(NSMutableArray*)演员是不必要的.知道伤害,但如果不需要它,为什么要这样做呢?
(2)您需要保留listOfIntervals.+ arrayWithArray:将创建一个自动释放的数组,因此,该数组released在对象初始化之后,这将导致您看到的崩溃.
(3)-copy&-mutableCopy返回保留的对象,无需调用-retain.
但是,您还需要修复-dealloc方法:
- (void)dealloc {
// move this [super dealloc];
[listOfIntervals release];
[currentValue release];
[title release];
[super dealloc]; // to here
}
Run Code Online (Sandbox Code Playgroud)
在[super dealloc] 必须始终是最后一个.-dealloc并没有什么神奇之处,因此,通过首先调用该函数,您告诉实例释放自己然后通过并清理实例变量.这将导致第二次崩溃(或意外行为).
总的来说,我建议你重新阅读内存管理指南.
http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
| 归档时间: |
|
| 查看次数: |
3636 次 |
| 最近记录: |