我对 iphone 开发很陌生,我的应用程序遇到了奇怪的崩溃。事实上,我的应用程序总是在模拟内存警告后崩溃。我每次都可以重现这种行为,并设法隔离了故障线路:)。
我在自定义 UITableViewController 中工作,提供自定义 UITableViewCells。
@implementation CustomTableViewController
// [...]
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"MyTableViewCell";
UITableViewCell *cell = nil;
if ([indexPath row] < [dataList childCount])
{
cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell)
{
cell = [[[KpowUITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
KUICustomView* customView = [[KUICustomView alloc]initWithFrame:CGRectZero];
[(KpowUITableViewCell*)cell setFrontView:customView];
[customView release];
}
KUICustomView* cView = [(KpowUITableViewCell*)cell frontView];
[cView setDataObject:[dataList getChildAtIndex:[indexPath row]]]; // The crash happens in this function
}
// [...]
这是我为单元格视图设置自定义数据对象的函数:
-(void)setDataObject:(DataObject *)do
{
[do retain];
[dataObject release];
dataObject = do;
NSString* defaultPath = [NSString stringWithFormat:@"%@/default_image.png", [[NSBundle mainBundle] resourcePath]];
UIImage* defaultImage = [[UIImage alloc] initWithContentsOfFile:defaultPath];
[self setImage: defaultImage];//[UIImage imageNamed:@"default_image"]]; // The crash happens in this function
[defaultImage release];
// [...]
最后,这就是魔法发生的地方:
-(void)setImage:(UIImage *)img
{
[img retain];
NSLog(@"setImage : old image > %@/%@/%i", [image description], [[image class]description], [image retainCount]);
[image release]; // CRASH EXC_BAD_ACCESS
image = img;
[self setNeedsDisplay];
}
因此,在正常情况下一切正常。但是,如果我模拟内存警告,滚动我的 UITableView 并调用所有这些函数,应用程序就会崩溃。如果我删除 [image release],则不会崩溃(但是'Hai there memory leaks')。NSLog 的输出总是类似于:
setImage : old image > <UIImage: 0x4b54910>/UIImage/1
我真的看不出我做错了什么,或者我可以做些什么来解决这个问题。这是 Xcode 调试器的屏幕截图...
http://img30.imageshack.us/i/debuggerscreen.png/
欢迎任何帮助。提前致谢
编辑 1: @bbum Build and Analyze 向我展示了一些不相关的警告,但仍然有用。甚至没有看到它在那里
我在另一个地方设置了图像。在 中setDataObject
,图像只是一个占位符。我异步启动了真实图像的下载,然后将其恢复为requestDidFinishLoad
. 方法是这样的:
- (void)requestDidFinishLoad:(KURLRequest*)request
{
if (request == currentRequest)
{
UIImage* img = [[UIImage alloc] initWithData:[request data]];
if (nil != img)
[self setImage:img];
[img release];
}
if (currentRequest == request)
currentRequest = nil;
[request release];
}
我用 NSZombie Detection 运行了仪器,结果似乎指向了另一个方向。这是一个屏幕截图:
http://img13.imageshack.us/i/zombieinstrument.jpg/
我不太确定该怎么做,但调查正在进行中:)