【问题标题】:Locating a memory leak/source of over-release crach定位内存泄漏/过度释放裂缝的来源
【发布时间】:2011-05-18 03:46:30
【问题描述】:

谁能帮我弄清楚我应该在哪里发布exerciseArray?我在dealloc 中遇到了崩溃,当我在调用sortedArray 之前释放时。此代码被多次调用。

//Set exerciseArray
review.exerciseArray = [[workout assignedExercises] allObjects];

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"viewWillAppear");
    NSString *workoutName =  [event.assignedWorkout valueForKey:@"name"];
    self.title = workoutName ;

    NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"index"
                                                                    ascending:YES] autorelease];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    [sortedArray release];
    sortedArray= [exerciseArray sortedArrayUsingDescriptors:sortDescriptors];
    NSLog(@"*****SORTEDARRAY****** %d",[sortedArray retainCount]);
    for (Exercise *ex in sortedArray){
        NSLog(@"%@ %@ %@",ex.name , ex.repCount, ex.weight);
    } 
    NSLog(@"*********************");
    [sortedArray retain];
    [self.tableView reloadData];
}

 - (void)dealloc {
    [super dealloc];

    [managedObjectContext release];
    [event release];
}

【问题讨论】:

  • 移动[super dealloc],所以它是你的dealloc处理程序中的最后一件事。
  • 为什么会有不同?
  • “超级”是保存您自己的对象的容器,因此在执行[super dealloc] 之后,您自己的成员变量将不再可访问——因此当您尝试释放它们时会出现错误。先释放自己的变量,最后告诉super释放。有关更多信息,请参阅此主题:stackoverflow.com/questions/3523576/…
  • @Steve:为了将来,请考虑将制表符转换为空格,然后再发帖;自动格式化程序不适用于行首的制表符,而且您的代码看起来很有趣。谢谢!
  • @Josh 没问题,感谢您的提示。

标签: objective-c ios memory-management dealloc


【解决方案1】:

首先要做的事情:您应该将[super dealloc] 调用移到dealloc 方法的末尾。首先处理您的自定义变量,然后您要做的最后一件事是将 dealloc 推送到超类以处理其余的清理工作。


现在,我很担心里面的[sortedArray release][sortedArray retain]。您应该做的是,为了节省在 sortedArray ivar 上实现 retain/release 的语义,为 sortedArray 声明一个属性,如下所示:

// this goes in your @interface
@property (nonatomic, retain) NSArray *sortedArray;

// this goes in your @implementation
@synthesize sortedArray;

现在您可以轻松设置sortedArray,而无需担心保留或释放:

// note the use of self, this is required
self.sortedArray = [exerciseArray sortedArrayUsingDescriptors:sortDescriptors];

您现在可以删除releaseretain 调用,因为这是自动处理的。确保在您的 dealloc 方法中添加一行以清理变量。

self.sortedArray = nil;

..它将为您调用阵列上的release

编辑: 这也适用于 exerciseArray,这是您的实际问题。只要涉及到 Cocoa 类,您就可以使用@property (retain)@synthesize 简化内存管理。对于NSInteger 和其他原始类型,或者当您不想持有对该对象的拥有引用时,请改用@property (assign)

【讨论】:

  • 为什么是自我。必需的?每当我调用 sortedArray 时都需要它吗?
  • 您必须使用self 告诉编译器您不是直接引用变量sortedArray,而是想使用为您生成的方法setSortedArray: @synthesize。这很好,因为setSortedArray: 包含所有retainrelease 操作,否则如果您只使用sortedArray = ...,则必须自己编写。
  • 如果您正在读取变量sortedArray,例如查看数组中的对象,则不需要。在这种情况下,请随意使用sortedArray
  • 我刚刚阅读了 Apple 的内存管理编程指南,非常有帮助。 developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/…
猜你喜欢
  • 2012-06-08
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
相关资源
最近更新 更多