【发布时间】:2010-08-18 23:48:32
【问题描述】:
我最近(经过数小时的调试)在一个 Objective-C iPad 应用程序中发现了一个段错误。归结起来,我有一个对象 TOP,它拥有 MIDDLE,它拥有 BOTTOM。 MIDDLE 和 BOTTOM 的保留计数为 1。MIDDLE 将 BOTTOM 传递给 TOP 中的一个方法,该方法最终释放了 MIDDLE,从而导致 BOTTOM 被释放并释放。当 TOP 中的相同方法继续使用 BOTTOM 时,它出现了段错误。 (请注意,为了简单起见,我在描述中省略了多层间接,但这让调试变得很麻烦。)
发生的事情有名字吗?有没有我可以遵循的模式来防止它在未来发生?为什么运行时不通过使用 [self retain] 和 [self release] 包装方法(或以相同方式或两者兼而有之)来保留调用堆栈上的对象?
编辑:
需要明确的是,当 TOP 释放 MIDDLE 时,它会将指针设置为 nil。永远不会通过无效指针访问 MIDDLE。
编辑 2: 我应该首先发布实际代码。这基本上就是我所拥有的:
// also known as TOP
@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
UIViewController* controller;
}
@end
@implementation MyAppDelegate
- (void)displayDoc:(Document*)doc {
DocController* c = [[DocController alloc] initWithNibName:@"DocController" bundle:nil doc:doc];
[controller release];
// controller was previously an instance of HomeController
controller = c;
}
- (void)displayBookmark:(Bookmark*)bookmark {
[self displayDoc:bookmark.document];
[controller setPage:bookmark.page];
}
- (void)dealloc {
[controller release];
[super dealloc]
}
@end
// also known as MIDDLE
@interface HomeController : UIViewController {
}
@end
@implementation HomeController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Bookmark* b = ...; // pull out of existing data structure, not created here
MyAppDelegate* app = ...;
[app displayBookmark:b];
}
@end
// also known as BOTTOM
@interface Bookmark : NSObject {
}
@property NSString* name;
// etc.
@end
【问题讨论】:
标签: objective-c memory-management