我有UIView
,其中包含UITableView
。此表格由NSMutableArray
填充。
我在UIView的initWithFrame:
方法中初始化了数组和表。
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
bookTable = [[UITableView alloc]initWithFrame:CGRectMake(100, 108, 260, 535)];
bookArray = [[NSMutableArray alloc]init]; //this array will be populated later
//other codes
}
return self;
}
我在dealloc
中发布了它们:
- (void)dealloc
{
[bookTable release];
[bookArray release];
[super dealloc];
}
问题是当应用程序在dealloc
崩溃时。它产生错误:[CALayer release]: message sent to deallocated instance 0x82db660
我在我的代码中到处查看,我确信我没有过度发布任何内容。我决定删除[bookArray release]
中的dealloc
,它就会停止崩溃。我跑了Analyze
并没有给我任何潜在的泄漏。
有人可以向我解释为什么在dealloc中释放数组会导致崩溃吗?
注意: 表和数组都是视图的实例变量。
修改 填充数组的代码:
NSString *sql = [NSString stringWithFormat:@"SELECT BookName FROM books WHERE UserID=%d", userId];
booksArray = [sqlite executeQuery:sql];
请注意我使用的是sql包装器。
答案 0 :(得分:0)
问题在这里,我假设。
booksArray = [sqlite executeQuery:sql];
executeQuery
方法可能会返回一个自动释放的NSMutableArray,或类似的内容可能会写在executeQuery
NSMutableArray* tempArray = [NSMutableArray arrayWithCapacity:0];
如果它是这样的,它应该已经处于自动释放模式,因此release
方法中没有dealloc
。
<强>更新强>
此外,as0sign属性为数组。
@property (nonatomic, retain) NSMutableArray* booksArray;
然后,无论您在何处使用它,请将其用作self.booksArray
self.booksArray = [sqlite executeQuery:sql];
这样,它将是正确的内存管理,然后在dealloc中释放数组。
答案 1 :(得分:0)
这就是问题所在
booksArray = [sqlite executeQuery:sql];
sqlite
返回的数组是一个自动释放的对象。您必须保留它或从`dealloc'中删除释放。
booksArray = [[sqlite executeQuery:sql] retain];
由于它是自动释放的对象,因此当系统也尝试release
时,以dealloc释放它会导致崩溃。
并且在init
方法中删除数组初始化,这是多余的。
答案 2 :(得分:0)
executeQuery
方法的退货声明,例如[array autorelease]
booksArray = [sqlite executeQuery:sql];
替换为booksArray = [[sqlite executeQuery:sql] retain];
如果您为property
booksArray
写了@property(nonatomic, retain) NSMutableArray *bookArray;
,那么您可以将{strong>第2步替换为self.bookArray = [sqlite executeQuery:sql];
您的问题是您从executeQuery
方法返回已发布的对象(您在评论中提到了它)。这就是你得到错误的原因
答案 3 :(得分:0)
我建议为booksArray创建一个属性:
@property (nonatomic, retain) NSMutableArray *bookArray;
当您填充它时,请尝试以下代码:
self.bookArray = [NSMutableArray arrayWithArray:[sqlite executeQuery:sql]];
这将创建一个自动释放的返回数组副本,然后由属性“自动”获取。
当然你应该确保通过[sqlite executeQuery:sql]返回的数组是自动释放的。