2012-06-15 5 views
0

과도하게 릴리스 된 객체로 인해 내 응용 프로그램이 충돌하고 사용자 정의 클래스에서 dealloc의 초기 호출로 축소했습니다. 이것은 아래의 사용자 정의 클래스를 사용하는있는 NSMutableArray에 의한 충돌이 발생 :초기 dealloc 호출 over-release object iOS

#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; 

} 
[i가 출시]에

좀비 점; 그러나 이것은 충돌을 초래하지 않는 이전에 호출 된 정확한 진술입니다.

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

value 속성을 어떻게 선언합니까? –

+1

흥미로운 코드는 아마도 GraphData 객체를 선언하고, 생성하고, 유지할 때 어디에나있을 것입니다. –

+0

추가 코드로 위 질문을 편집했습니다. – Jace

답변

0

[i release] 문제가 있습니다. dataForPlotActionNote 안에있는 객체에 대한 참조를 얻으면 보유 수를 늘리지 않으므로 카운트를 줄여서는 안됩니다. 당신이 [item release]는 점에서 다른 사용

장소 당신은 alloc와 그 객체를 생성하기 때문에 그들을 유지 한을했습니다.

+0

네, 맞습니다. GraphData 항목을 추가 할 때; 나중에 그들을 참조 할 때 그렇지 않다. 다른 배열은 똑같은 방식으로 참조되고 over release 된 객체는 dataForPlotActionNote에 대해서만 발생하기 때문에 이상합니다. 나는 그것으로 주위를 돌며 내가 재 배열 할 수있는 것을 보게 될 것이다. – Jace

+0

몇 가지 변경 사항이 있으며 누출없이 완벽하게 작동합니다. 내 질문을보고이 문제를 지적 해 주셔서 감사합니다. 이는 개발 마지막 달 동안 프로젝트를 상속 할 때 발생할 수있는 잠재적 함의의 좋은 예입니다. – Jace

+0

"Product-> Analyze"명령은 종종 이와 같은 것을 지적 할 수 있습니다. –