【问题标题】:Memory Leak, Re-assigning NSArray Property内存泄漏,重新分配 NSArray 属性
【发布时间】:2012-03-07 10:53:03
【问题描述】:

我有一个由NSArray 属性支持的UITableView。数组被声明为属性:

@property (nonatomic, retain) NSArray *events;

@synthesize events;

并用于以下方法。 Instruments 不断告诉我 populateEvents 导致泄漏。我已经尝试了此代码的多种变体,但最终还是会出现更多泄漏或EXC_BAD_ACCESS

- (void)viewDidLoad
    {
        self.events = [self populateEvents];
    }

    - (void)updateData
    {   
        events = nil;
        self.events = [self populateEvents];

        [self.tableView reloadData];
    }

    - (NSArray*)populateEvents
    {
        NSMutableArray *response = [[NSMutableArray alloc] init];

        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM Event"];
        sqlite3_stmt *statement = [database prepare:sql];

        if(statement != nil)
        {
            // Loop through the results and add them to the response
            while(sqlite3_step(statement) == SQLITE_ROW)
            {
                Event *event = [[Event alloc] init];
                event.subject = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
                e

                [response addObject:event];
                [event release];
            }
            sqlite3_finalize(statement);
        }
        return [response autorelease];
    }

更新 很多人都在询问事件类:

@interface Event : NSObject

@property (nonatomic) NSInteger Id;
@property (nonatomic, retain) NSString *subject;
@property (nonatomic, retain) NSString *details;
@property (nonatomic, retain) NSString *startTime;
@property (nonatomic, retain) NSString *endTime;
@property (nonatomic, retain) NSString *eventType;
@property (nonatomic, retain) NSString *employee;

@end

- (void)dealloc
{
    [super dealloc];

    [subject release];
    [details release];
    [startTime release];
    [endTime release];
    [eventType release];
    [employee release];
}



- (NSString*)startTime
{
    return [self humanReadableDate:startTime];
}



- (NSString*)endTime
{
    return [self humanReadableDate:endTime];
}



- (NSString*)humanReadableDate:(NSString*)isoDate
{
    NSDateFormatter* formatter = [[[NSDateFormatter alloc]init]autorelease];
    [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];

    NSDate* date = [formatter dateFromString:isoDate];

    [formatter setDateFormat:@"MMM dd yyyy HH:mm"];
    NSString* humanrReadable = [formatter stringFromDate:date];

    return humanrReadable;
}
@end

【问题讨论】:

  • 你的代码中有什么需要events = nil
  • 如果我不在 populateEvents 中自动释放响应,则没有 exc_bad_access 但仍然存在泄漏

标签: iphone objective-c memory-management memory-leaks


【解决方案1】:

这是一个泄漏,因为您将 NSArray(事件)的指针更改为 nil 而不释放先前的对象。您丢失了指向先前数组的指针,因此发生了泄漏。

改变你的

events = nil;

self.events = nil;

【讨论】:

  • 如果使用 self.events = nil,我会得到 EXC_BAD_ACCESS
  • 它不应该,真的,它可能是导致它的其他一些东西。另外,你可以把那一行全部删除,不需要那行代码。
  • X 斜线是正确的。如果您仍然遇到问题,那么您的代码中其他地方可能存在更多错误。我冒险猜测Event 类上的subject 属性未声明为retaincopy
【解决方案2】:

您应该在调用[super dealloc]之前释放Events类中的内部对象。

并在 updateData 方法中删除 events = nil;。这是不必要的,即使在您修复 Events 类之后也会导致问题。

【讨论】:

    【解决方案3】:

    问题就出来了

    event = nil;
    

    由于您的属性设置为保留,因此事件指向 nil 而不会释放先前的内存。

    您可以拨打self.events = [self populateEvents]; 它会在分配之前先释放前一个 obj 并保留该 obj。

    【讨论】:

    • 嗨 Hanon 删除事件 = nil 给了我 EXC_BAD_ACCESS
    • Event的结构是什么?
    【解决方案4】:

    只需在您的 XCode 项目组和文件窗格中设置此环境变量, 你会发现 Executables -> Your Application -> Right Click -> Get Info -> Arguments Tab -> Environment Variables

    名称:NSZombieEnabled
    值:是的

    如果有任何对象多次释放访问该值,这将帮助您找到对象的僵尸对象。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多