【问题标题】:Memory Management Headache内存管理头痛
【发布时间】:2012-03-01 16:37:34
【问题描述】:

如果我不把它放在 dealloc 中,我会得到泄漏。如果我这样做,我会崩溃EXC_BAD_ACCESS。我看不出这段代码有什么问题。错误访问指向[events release]。是我在下面的代码中犯了一个错误,还是 Instruments 只是在嘲笑我的付出?

eventsNSArray

@interface EventsViewController : UITableViewController 
{    
@private
    NSArray *events;
}

 - (void)viewDidLoad
    {
        events = [[self getEvents] retain];
    }

    - (void)dealloc
    {
        [events release];
        [super dealloc];
    }

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

       //Some sql
       while(sqlite3_step(statement) == SQLITE_ROW)
       {
           Event *event = [[[Event alloc] init] autorelease];
           event.subject = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];

          [response addObject:event];
       }
       return response;
    }

更新 你们中的很多人都说代码很好,这是一个优点。我不会在其他地方操纵events - 我已经删除了任何试图找出崩溃的代码。也许它在父视图中?

这是推送EventsViewController的点击事件: - (void)eventsClick:(id)sender

{
    EventsViewController *eventsViewController = [[EventsViewController alloc] initWithNibName:@"EventsViewController" bundle:nil];
    eventsViewController.anywhereConnection = anywhereConnection;
    eventsViewController.contact = contact;

    [[self navigationController] pushViewController:eventsViewController animated:YES];
    [eventsViewController release];
}

当我返回父视图时,崩溃实际上正在发生。 (我认为在这种情况下它被认为是父母)。但也许[eventsViewController release] 只是在EventViewController 中触发dealloc

【问题讨论】:

  • 该代码没有错误。请发布更多您的代码.. 可能您在代码的另一点更改了成员变量事件?
  • 编码约定指定只有返回结果与引用参数的方法才能具有前缀“get”。否则会导致混乱。
  • events 是如何声明的,它是一个属性,如果是,请提供代码。另外,强烈考虑使用 ARC。
  • events 不是一个属性,只是一个变量。关于“get”的好点是我懒惰的。我会发布更多代码。
  • 您是否尝试启用 NSZombies ?

标签: iphone ios memory-management memory-leaks


【解决方案1】:

您是否考虑过重构代码以使用 ARC?它适用于 iOS 4 及更高版本,让您的生活更轻松。有很多教程可以指导您如何操作,并且无需手动找出内存管理的细微差别。

【讨论】:

  • 嘿,这个 ARC 的东西看起来不错。我浪费了太多时间来解决内存管理问题。感谢您的提醒。
【解决方案2】:

如果您的 Events 对象将属性“subject”设置为 assign,则不会保留 stringWithUTF8String: 的结果。 (如果 Events 是 C++ 对象,也是一样。)

stringWithUTF8String: 方法返回一个自动释放的对象,该对象将在事件循环的下一轮释放。

【讨论】:

    【解决方案3】:

    通过“self”引用变量和不通过“self”引用变量时存在巨大差异。

    当你使用

    events = [[self getEvents] retain];
    

    在 getEvents 中分配的内存永远不会存储在类属性中,基本上是泄漏。

    你需要使用

    self.events = [self getEvents]; // no need to use retain if property is correctly defined.
    

    然后

    [events release]; 
    

    应该可以正常工作。

    【讨论】:

      【解决方案4】:

      试试看

      events = nil; 
      

      在释放。

      【讨论】:

        猜你喜欢
        • 2011-03-19
        • 2012-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 2011-07-21
        • 2012-03-21
        相关资源
        最近更新 更多