【问题标题】:What is the source of the leaky object for this code?此代码的泄漏对象的来源是什么?
【发布时间】:2011-09-01 10:03:45
【问题描述】:

任何人都可以帮助重新定义此代码的泄漏对象的来源:

我的应用程序编译时没有任何 ANALYZE 问题。当我运行 PROFILER 并查看 Memory Leaks 时,我看到出现了泄漏。其中一个泄漏在我的 WeekendEvent 对象中。下面的仪器中有 3 个 Leaked Block 行项(我在代码中指出了这些项):

  • 马洛克+1
  • 保留+2
  • 释放+1

问题 - 我认为这意味着有一个版本,但是这个泄漏是从哪里来的。我的代码中点击工具突出显示的部分如下。对我来说,这似乎还不错:

  1. 我创建的 WeekendEvent 在传递到 addWeekendEvent 方法后释放
  2. 在 addWeekendEvent 中,它只是将其添加到 NSMutableArray,因此我认为该安排对其包含的对象进行任何内存管理
  3. 我也确实在 dealloc 中释放了 NSMutableArray

关键源代码位和仪器亮点

// ------Weekends Method (plural)-----
WeekendEvent *weEvent = [[WeekendEvent alloc] init]; // [INSTRUMENTS - 87.5%]
[week addWeekendEvent:weEvent];                      // [INSTRUMENTS - 12.5%]
[weEvent release];                  


//------Weekend *.h ------------
@interface Weekend : NSObject {
    NSMutableArray*     _events;     
}
- (void)addWeekendEvent:(WeekendEvent*)weEvent;
@property (nonatomic, retain) NSMutableArray* events;
@end


//------Weekend *.m -------------
- (void)addWeekendEvent:(WeekendEvent*)weEvent {
    [self.events addObject:weEvent];
}
- (void) dealloc {
    [_events release];
    [super dealloc];
}

编辑:关于如何创建/使用上面的“week”变量的一些附加代码 - 所以在周末方法中,我发布的代码位于 for 循环中 - 显示了 for 循环的代码因此是:

for (Weekend *week in self.items) {
   // do pass "week.start" to some methods (which is an NSDate) - don't think this would be relevant though?
   WeekendEvent *weEvent = [[WeekendEvent alloc] init]; // [INSTRUMENTS - 87.5%]
   [week addWeekendEvent:weEvent];                      // [INSTRUMENTS - 12.5%]
   [weEvent release];   
}               
// Note - self.items I checked is "released" in the dealloc method

编辑 2 - 确认一下,它是 Instruments 在其“泄漏对象”列中突出显示的“WeekendEvent”实例。以防万一这不清楚。

EDIT 3 - 关于我如何设置 items 变量 - 关键代码位是:

@interface Weekends : NSObject {
    NSMutableArray* _items;
}
@property (nonatomic, retain) NSMutableArray* items;

@synthesize items = _items;
- (void) dealloc {
    [_items release];
    [super dealloc];
}

【问题讨论】:

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


    【解决方案1】:

    您显示的代码中的内存管理是正确的,假设您的 Weekend 类的其余部分如下所示:

    @synthesize events = _events;
    
    - (id)init {
        if ((self = [super init]) == nil) { return nil; }
        _events = [[NSMutableArray alloc] initWithCapacity:0];
        return self;
    }
    

    此外,仪器结果与您的所有代码匹配:

    Malloc  +1  ==  WeekendEvent *weEvent = [[WeekendEvent alloc] init];
    Retain  +2  ==  [week addWeekendEvent:weEvent];
    Release +1  ==  [weEvent release];
    

    基于该逻辑,最有可能的候选者是您的 week 对象未正确释放。您还没有展示解释它是如何创建的代码,但我确实注意到您发布的代码 是针对Weekend 类的。您确定week 不是其他类型吗?

    【讨论】:

    • @e.James 好奇:为什么是_events = [[NSMutableArray alloc] initWithCapacity:0];,而不仅仅是_events = [NSMutableArray new];
    • @Justin:简短的回答是“约定”。稍长一点的答案是 alloc/init... 成语符合 Apple 的编码标准,并且还允许您根据需要添加参数。更多细节在这里:stackoverflow.com/questions/719877/…
    • 抱歉 - 我应该换一种措辞:为什么你更喜欢 initWithCapacity:0 而不是 init
    • 没有充分的理由:) 第一次需要NSMutableArray,我查阅了文档,因为initWithCapacity: 是唯一列出的初始化程序(其他初始化程序继承自NSArray),那是我一起去的。
    • @e.James initWithCapacityNSMutableArray 文档中唯一的初始化程序,因为继承自 NSArray,它已经拥有所有 NSArray 构造函数,这些构造函数仅在 NSArray 文档中. Apple 文档通常不会重新描述继承的方法。但这并不意味着它是设计好的。我敢打赌,[[NSMutableArray alloc] init] 使用 initWithCapacity: 和默认(合理)值,就像大多数语言一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多