【问题标题】:Memory management advice - how to handle Zombies?内存管理建议 - 如何处理僵尸?
【发布时间】:2012-02-25 02:46:34
【问题描述】:

在下面的示例代码中,我有点不明白为什么我会上线 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"];
}

【问题讨论】:

  • 您是否使用ARC?另外,也许您可​​以显示您的 Category getInitialDataToDisplay: 类方法。
  • 和你的 [self getDBPath] 方法。
  • 另外你不应该在你的交易中使用 [object autorelease]。使用[对象释放]。
  • 如果错误确实来自该行,则几乎可以肯定是 getInitialDataToDisplay 或 getDBPath 中的问题,您都没有提供。
  • 很抱歉。我现在在上面的帖子中包含了这两种方法。让我知道可能导致问题的原因。

标签: iphone objective-c memory


【解决方案1】:

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

祝你好运!

【讨论】:

  • 感谢 Nico,我喜欢 Build + Analyze 的外观,但老实说,我不知道如何处理这些数据。那是我的问题 - 我正在尝试了解谁可以更好地管理对象并需要一些指导。
  • 它将生成一个蓝色选项卡,如果您单击该选项卡,它将指向它认为导致问题的行。 developer.apple.com/library/mac/#documentation/IDEs/Conceptual/…
【解决方案2】:
categories = [[NSMutableArray alloc] init];
.
.
//Initialize the Category array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.categories = tempArray;
[tempArray release];

你已经设置了类别,然后设置了 tempArray,用它替换了 category 中的那个,从而造成了泄漏,然后释放了 temp arrayObject,它现在还指向什么类别,所以除非 "self.categories" 是一个保留属性这将是一个僵尸。那里似乎有什么问题。 我可能需要查看更多您的代码(属性声明及其综合以确保。

是在“getInitialDataToDisplay”或“getDBPath”上调用的僵尸 尝试将其分成 2 行以了解更多准确点

【讨论】:

    【解决方案3】:

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

        @property (nonatomic, retain) NSArray Category;
    

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

        @synthesize Category;
    

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

    【讨论】:

      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 1970-01-01
      相关资源
      最近更新 更多