内存管理建议 - 如何处理僵尸?

时间:2012-02-25 02:46:34

标签: iphone objective-c memory

在下面的示例代码中,我有点迷失为什么我会在线上获得一个NZombie:

[Category getInitialDataToDisplay:[self getDBPath]];

我已经浏览过SO帖子和其他文档,但我是Objective-c的新手,我正在转动这个问题。

- (void)applicationDidFinishLaunching:(UIApplication *)application {

//Copy database to the user's phone if needed.
[self copyDatabaseIfNeeded];

// Init the Array
activeCategories = [[NSMutableArray alloc] init];
activeSubjects = [[NSMutableArray alloc] init];
categories = [[NSMutableArray alloc] init];
subjects = [[NSMutableArray alloc] init];
quotes = [[NSMutableArray alloc] init];
quoteMaps = [[NSMutableArray alloc] init];

//Initialize the Category array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.categories = tempArray;
[tempArray release];

//Once the db is copied, get the initial data to display on the screen.
[Category getInitialDataToDisplay:[self getDBPath]];


//populate active subjects and categories: 

activeCategories = [self getActiveCategories];
activeSubjects = [self getActiveSubjects];

// sort data

NSSortDescriptor *categorySorter;
NSSortDescriptor *subjectSorter;

categorySorter = [[NSSortDescriptor alloc]initWithKey:@"category_title" ascending:YES];
subjectSorter = [[NSSortDescriptor alloc]initWithKey:@"title" ascending:YES];

NSArray *sortDescriptorsCat = [NSArray arrayWithObject:categorySorter];
NSArray *sortDescriptorsSub = [NSArray arrayWithObject:subjectSorter];

[self.categories sortUsingDescriptors:sortDescriptorsCat];
[self.subjects sortUsingDescriptors:sortDescriptorsSub];

[categorySorter release];
[subjectSorter release];

// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}

...

- (void)dealloc {

[activeSubjects release];
[activeCategories release];

[categories autorelease];
[subjects autorelease];
[quotes autorelease];
[quoteMaps autorelease];
[navigationController release];
[window release];
[super dealloc];
}

这是getInitialDataToDisplay:

+ (void) getInitialDataToDisplay:(NSString *)dbPath {

// Use this section to bring in database and populate the array
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];    
[database open];

QuotesAppDelegate *appDelegate = (QuotesAppDelegate *)[[UIApplication sharedApplication] delegate];


//appDelegate.categories = [appDelegate.categories sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

//POPULATE THE SUBJECT 
FMResultSet *result_subjects = [database executeQuery:@"select * from SUBJECT"];

while([result_subjects next]) {

    NSInteger primaryKey = [result_subjects intForColumn:@"SUBJECT_ID"];
    Subject *sub = [[Subject alloc] initWithPrimaryKey:primaryKey];

    sub.title = [result_subjects stringForColumn:@"SUBJECT"];
    sub.category_title = [result_subjects stringForColumn:@"CATEGORY"];
    sub.active = [result_subjects intForColumn:@"ACTIVE"];
    sub.isDirty = NO;

    [appDelegate.subjects addObject:sub];
    [sub release];

}

FMResultSet *result_categories = [database executeQuery:@"select distinct category from SUBJECT"];

while([result_categories next]) {

    Category *cat = [[Category alloc] init];

    cat.category_title = [result_categories stringForColumn:@"CATEGORY"];
    NSLog(@"loading category: %@", cat.category_title);

    QuotesAppDelegate *appDelegate = (QuotesAppDelegate *)[[UIApplication sharedApplication] delegate];

    for (Subject *sb in appDelegate.subjects){

        if([cat.category_title isEqualToString:sb.category_title]){
            [cat.subjects addObject:sb];
            NSLog(@"   Adding subject: %@ cat.subjects.count=%i", sb.title, cat.subjects.count);

        }

    }

    [appDelegate.categories addObject:cat];
    [cat release];

}

//POPULATE THE QUOTES 
FMResultSet *result_quotes = [database executeQuery:@"select * from QUOTE"];

while([result_quotes next]) {

    Quote *sub = [Quote alloc];

    sub.quote_id = [result_quotes stringForColumn:@"QUOTE_ID"];
    sub.quote_date = [result_quotes stringForColumn:@"DATE"];
    sub.title = [result_quotes stringForColumn:@"DESC1"];
    sub.desc2 = [result_quotes stringForColumn:@"DESC2"];
    sub.excerpt = [result_quotes stringForColumn:@"EXCERPT"];
    sub.note = [result_quotes stringForColumn:@"NOTES"];
    sub.isDirty = NO;

    [appDelegate.quotes addObject:sub];
    [sub release];

}    


//POPULATE THE QUOTE_MAPS 
FMResultSet *result_quote_map = [database executeQuery:@"select * from QUOTE_MAP"];

while([result_quote_map next]) {

    QuoteMap *sub = [QuoteMap alloc];

    sub.quote_id = [result_quote_map stringForColumn:@"QUOTE_ID"];
    sub.quote_map_id = [result_quote_map stringForColumn:@"QUOTE_MAP_ID"];
    sub.subject_id = [result_quote_map stringForColumn:@"SUBJECT_ID"];
    sub.isDirty = NO;

    [appDelegate.quoteMaps addObject:sub];
    [sub release];

}    

[database close];

NSLog(@"Count of categories: %i", appDelegate.categories.count);
NSLog(@"Count of subjects: %i", appDelegate.subjects.count);
NSLog(@"Count of quotes: %i", appDelegate.quotes.count);
NSLog(@"Count of quoteMaps: %i", appDelegate.quoteMaps.count);

}

这是getDbPath:

- (NSString *) getDBPath {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:@"reference.db"];
}

3 个答案:

答案 0 :(得分:2)

有时,最好的办法是构建 - >分析(cmd shift b)。这几乎可以在所有情况下立即指出你的错误。

祝你好运!

答案 1 :(得分:1)

categories = [[NSMutableArray alloc] init];
.
.
//Initialize the Category array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.categories = tempArray;
[tempArray release];

你已经设置了类别,然后设置tempArray,用它替换类别中的那个,从而产生泄漏,然后释放temp arrayObject,现在哪些类别也指向,所以除非"self.categories"是一个保留财产它将是一个僵尸。那里似乎有些不对劲。 我可能需要查看更多代码(属性声明及其合成以确保。

是Zombie调用“getInitialDataToDisplay”或“getDBPath” 尝试将其划分为2行以更多地了解引脚点

答案 2 :(得分:0)

我认为你没有在.h文件中声明Category作为保留属性。如果没有,请在.h文件中添加以下行

    @property (nonatomic, retain) NSArray Category;

并将.m中的属性合成为 -

    @synthesize Category;

我认为这会有所帮助......