此发布调用是不是会导致仪器崩溃?

Posted

技术标签:

【中文标题】此发布调用是不是会导致仪器崩溃?【英文标题】:Is this release call causing instruments to crash?此发布调用是否会导致仪器崩溃? 【发布时间】:2011-03-02 21:17:30 【问题描述】:

我有一个名为 CategoryViewController 的类,它的 viewDidLoad 方法调用了这个方法:

  - (void)reset 
    Category * c = [[Category alloc] initWithId:0 title:@"Categories"];
    [self setCategory:c];
    [c release];  // <--- line of code I am interested in
    self.title = @"Categories";
    [self fillCategory];

在大多数情况下,此处的类别为空,但有时需要在分配类别后调用重置。如果没有我在代码中标记的行,程序构建和调试都很好,我可以拉起仪器并检查我的泄漏。我能找到的唯一泄漏是从此函数初始化的类别(因为没有释放,在已初始化的 CategoryViewController 上调用此函数时会发生泄漏)。

如果我尝试在 c、Instruments、XCode 和 Simulator 上按原样运行此方法,它们都会开始出现奇怪的行为,崩溃和冻结,给我随机的 SIGABRT 和 SIGKILL。我可以使用其中的代码行进行构建和调试,但 Instruments 甚至不会启动我的应用程序。谁能给我提示一下这里发生了什么?

编辑:更多代码

@implementation Category
@synthesize title, articleCount, seeAlso, categoryId, articles, subcategories;

- (id)initWithId:(NSInteger)cid title:(NSString*)t
    self.title = t;
    self.categoryId = cid;
    [self setArticles:[[NSMutableArray alloc] init]];
    [self setSubcategories:[[NSMutableArray alloc] init]];
    [self setSeeAlso:[[NSMutableArray alloc] init]];
    self.articleCount = 0;
    return self;

【问题讨论】:

如果我围绕这段代码创建一个简单的虚拟类,它会正常工作,因此我们无法根据您提供的内容诊断错误。我们需要看看initWithId:title:setCategory:背后的代码。 如何为category 声明@property category 是保留属性吗?如果是,那么您是否使用自己的方法覆盖 Apple 生成的 setter setCategory?如果是,那么您需要在该方法中保留传入的类别对象。在这里只是在黑暗中拍摄,因为给定的信息不足以知道导致崩溃的原因。 类别是保留属性 【参考方案1】:

有趣的是,在您花时间将这些问题发布到网上之后,这些问题似乎如此轻松地解决了。在发布 Category 初始化代码后,我意识到我没有正确释放我所做的分配。在像这样进行适当的内存管理后,我的泄漏和崩溃似乎都消失了:

- (id)initWithId:(NSInteger)cid title:(NSString*)t
    self.title = t;
    self.categoryId = cid;
    NSMutableArray * m = [[NSMutableArray alloc] init];
    [self setArticles:m];
    [m release];
    m = [[NSMutableArray alloc] init];
    [self setSubcategories:m];
    [m release];
    m = [[NSMutableArray alloc] init];
    [self setSeeAlso:m];
    [m release];
    self.articleCount = 0;
    return self;

【讨论】:

我仍然觉得奇怪的是,一个看似无关的代码行可能会导致 Instruments 在启动时崩溃而没有任何解释。【参考方案2】:

假设您的属性声明如下,我认为您突出显示的行没有任何问题,您的其余代码也没有:

@property (retain) Category *c;

只是在黑暗中拍摄,但上次 Xcode、Instruments 和 Simulator 做了一些疯狂的事情,我进行了无限递归。

您确定您的方法 fillCategory 不会以某种方式调用您的 viewDidLoadreset 方法吗? 当您在 reset 方法的第一行设置断点并逐步按照您的代码进行操作时会发生什么?

【讨论】:

以上是关于此发布调用是不是会导致仪器崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

仪器在僵尸时崩溃

XCode:仪器有堆栈跟踪吗?

核心情节使我的应用程序使用仪器崩溃

仪器处理何时停止

错误 - 未注册仪器!必须在注册仪器下运行

比较调用树选项在仪器中被禁用