我的应用程序由于过度释放的对象而崩溃,我已将其缩小到自定义类中dealloc的早期调用。这会导致崩溃归因于使用下面列出的自定义类的NSMutableArray:
#import <Foundation/Foundation.h>
@interface GraphData : NSObject{
NSInteger key;
NSString *value;
}
@property (nonatomic, readwrite) NSInteger key;
@property (nonatomic, retain) NSString *value;
-(id)initWithPrimaryKey:(NSInteger) xid;
-(id)initWithName:(NSString *)n key:(NSInteger)i;
@end
#import "GraphData.h"
@implementation GraphData
@synthesize key,value;
-(id)initWithPrimaryKey:(NSInteger) xid{
//[super init];
self=[super init];
if (self){
self.key = xid;
self.value = @"";
}
return self;
}
-(id)initWithName:(NSString *)n key:(NSInteger)i{
self=[super init];
if (self){
self.key = 0;
self.value = n;
}
return self;
}
-(void)dealloc{
NSLog(@"Say bye to %@, kids!", self);
[value release], value = nil;
[super dealloc];
}
@end
奇怪的是我在另一个类中使用GraphData,它没有问题。但是在这种情况下,在我合成NSMutableArray theNewData属性之前调用dealloc;但是在我合成了三次之后。
-(NSMutableArray*)fillDataInArray:(NSInteger)keyphrase_id{
NSLog(@"lsd");
NSLog(@"Keyphrase_id:%d", keyphrase_id);
NSDate *startdate = [self getDateForApplicationInstalled];
NSDate *enddate = [NSDate date];
NSString *dateString1=[[NSString alloc] initWithString: [fmt stringFromDate:startdate]];
NSString *dateString2=[[NSString alloc] initWithString: [fmt stringFromDate:enddate]];
NSMutableArray *newDataNew = [[NSMutableArray alloc]init];
self.theNewData = newDataNew;
[newDataNew release];
selStmt = nil;
// build select statement
if (!selStmt)
{
const char *sql = "select distinct position, key_time from ranking where keyphrase_id = ? and key_time between ? and ? order by key_time";
if (sqlite3_prepare_v2(database, sql, -1, &selStmt, NULL) != SQLITE_OK)
{
selStmt = nil;
}
NSInteger n = keyphrase_id;
sqlite3_bind_int(selStmt, 1, n);
sqlite3_bind_text(selStmt, 2, [dateString1 UTF8String] , -1, SQLITE_TRANSIENT);
sqlite3_bind_text(selStmt, 3, [dateString2 UTF8String] , -1, SQLITE_TRANSIENT);
NSLog(@"SQL query is: [%s]", sql);
}
if (!selStmt)
{
NSAssert1(0, @"Can't build SQL to read keyphrases [%s]", sqlite3_errmsg(database));
}
int ret;
while ((ret=sqlite3_step(selStmt))==SQLITE_ROW)
{
GraphData *item = [[GraphData alloc]init];
item.key = sqlite3_column_int(selStmt, 0);
item.value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selStmt,1)];
[self.theNewData addObject:item];
[item release];
}
sqlite3_reset(selStmt); // reset (unbind) statement
[dateString2 release];
[dateString1 release];
return theNewData;
}
它也可以通过其他方法访问:
-(NSMutableArray *) getDataForCharts:(int)seriesIndex{
NSLog(@"speed");
NSDate *startdate = [self getDateForApplicationInstalled];
NSDate *enddate = [NSDate date];
NSString *dateString1=[[NSString alloc] initWithString: [fmt stringFromDate:startdate]];
NSString *dateString2=[[NSString alloc] initWithString: [fmt stringFromDate:enddate]];
NSMutableArray *newDataNew = [[NSMutableArray alloc]init];
self.actionNoteData = newDataNew;
[newDataNew release];
selStmt = nil;
// build select statement
if (!selStmt)
{
const char *sql = "";
if (seriesIndex == 4) sql = "select distinct 105 score, notes_date from notes where iscompleted =1 and domain_id = ? and notes_date between ? and ? order by notes_date";
if (sqlite3_prepare_v2(database, sql, -1, &selStmt, NULL) != SQLITE_OK)
{
selStmt = nil;
}
NSInteger n = domain_id;
sqlite3_bind_int(selStmt, 1, n);
sqlite3_bind_text(selStmt, 2, [dateString1 UTF8String] , -1, SQLITE_TRANSIENT);
sqlite3_bind_text(selStmt, 3, [dateString2 UTF8String] , -1, SQLITE_TRANSIENT);
NSLog(@"SQL query is: [%s]", sql);
}
if (!selStmt)
{
NSAssert1(0, @"Can't build SQL to read keyphrases [%s]", sqlite3_errmsg(database));
}
// loop reading items from list
int ret;
while ((ret=sqlite3_step(selStmt))==SQLITE_ROW)
{
GraphData *item = [[GraphData alloc]init]; // create item
item.key = sqlite3_column_int(selStmt, 0);
item.value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selStmt,1)];
NSLog(@"Key:%d", sqlite3_column_int(selStmt, 0));
NSLog(@"Value:%s", sqlite3_column_text(selStmt,1));
[self.actionNoteData addObject:item]; // add to list
[item release]; // free item
}
sqlite3_reset(selStmt); // reset (unbind) statement
[dateString2 release];
[dateString1 release];
return actionNoteData;
}
Zombie指向[我发布];但这是前面提到的确切语句,不会导致崩溃。
if (index == 4) {
dateComponents.day = ([dateComponents day] -1 ) + dataindex + 1;
if (dataForPlotActionNote.count > dataindex) {
if ([dataForPlotActionNote objectAtIndex:dataindex]) {
GraphData *i = (GraphData *) [dataForPlotActionNote objectAtIndex:dataindex];
NSDate *date = [[[NSDate alloc] init] autorelease];
date =[fmt dateFromString:i.value];
datapoint.xValue = date;//[cal dateFromComponents:dateComponents];
datapoint.yValue = [NSNumber numberWithDouble:(i.key)];
[i release];
}
}
}
什么可能导致dealloc调用在执行代码的中途发生?
可以创建一个GraphData属性并在每次重置时帮助它保持足够长的活动吗?
答案 0 :(得分:0)
[i release]
问题是有道理的。当您获得对dataForPlotActionNote
内部对象的引用时,您不会增加其保留计数,因此您也不应该减少计数。
您使用[item release]
的地方不同,因为您使用alloc
创建了这些对象,因此执行会保留这些对象。