【问题标题】:Return object crashing iPhone返回对象使 iPhone 崩溃
【发布时间】:2010-10-10 03:33:43
【问题描述】:

我对 iPhone 开发者的整个世界还很陌生,所以如果这很简单,请原谅我。我有一个对象Card,上面有6 个Question 对象。当我说[card getQuestion:@"Art"] 时,我目前正在返回一个Question 对象,就像这样

- (Question*) getQuestion: (NSString*) questionType {
    Question *q = [questions objectForKey:questionType];
    return [q autorelease];
}

Question 的属性为text(NSString 类型),它允许我查看问题的文本是什么。所以我想用这个文本来更新viewController中的一个UILabel

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"%@", [[self.card getQuestion:@"Art"] qText]);
    self.myQuestion.text = [[self.card getQuestion:@"Art"] qText];
}

这会使 iPhone 崩溃,而如果我将对象 Card 中的函数更改为此

- (NSString*) getQuestion: (NSString*) questionType {
    return [[questions objectForKey:questionType] qText];
}

我在 viewController 中调用

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"%@", [self.card getQuestion:@"Art"]);
    self.myQuestion.text = [self.card getQuestion:@"Art"];
}

这很好用.. 任何人都可以解释我做错了什么,在这两种情况下,对 NSLog 的调用都会返回相关文本。在这两种情况下,显示器都会加载,但在第一种情况下它会在不久之后崩溃,而在另一种情况下它会保持稳定。

任何帮助表示赞赏。

【问题讨论】:

  • 如果有人回答了你的问题,你应该接受它。
  • 更正:如果有人用对您有帮助的解决方案回答了您的问题,您应该通过单击旁边的✔来接受它答案,将奖励作者。
  • @Emil 正确的答案并不总是有用的答案。
  • @Dave 我想你明白了。

标签: iphone objective-c


【解决方案1】:
- (Question*) getQuestion: (NSString*) questionType {
    Question *q = [questions objectForKey:questionType];
    return [q autorelease];
}

根据内存管理规则,您不应该自动释放该对象,这几乎肯定是导致崩溃的原因。您正在放弃您不拥有的对象的所有权,这导致它过早地被解除分配。这意味着当另一个假定拥有该问题的对象尝试访问它时,该问题消失了,您会因EXC_BAD_ACCESS 错误而崩溃。

此外,该方法可能应该称为questionForType:questionOfType:。使用get 前缀意味着该对象将通过一个输出参数返回,但事实并非如此。

【讨论】:

  • 破解了,非常感谢,我从某个地方找到的另一个示例中获取了自动释放的东西,但我认为那不是 iPhone 应用程序。哦,感谢功能提示,尝试使用命名约定
【解决方案2】:

由于您是新手 - 您绝对应该确保运行您的应用程序以寻找僵尸,并使用仪器应用程序运行它,以确保您不会在任何地方泄漏。

你应该每隔几天阅读 Objective - C 中关于内存管理的非常简短的解释 - 有一天它会完全融入并成为第二天性。

http://macdevelopertips.com/objective-c/objective-c-memory-management.html

【讨论】:

  • 是的,我已经阅读并理解了 Obj C 内存管理的基础知识,只是将其付诸实践的一个案例,这是我通过做错来学习的唯一方法。谢谢你的链接,我把它加了书签,会读几次:)
【解决方案3】:

我可以看到两个错误,

1:您正在发布您不拥有的东西(问题“q”) - 如果您执行分配、复制或保留,您应该释放它。如果没有,你不应该。

2:setter-line 应该这样写:

Question *q = (Question *)[questions objectForKey:questionType];

这样可以避免收到警告或错误。

【讨论】:

  • 1 是正确的,2 是不必要的。 objectForKey: 返回一个 id 类型的对象,可以安全地将其分配给任何对象变量而无需强制转换。
  • 我有时会在不投射对象(例如委托)时遇到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
相关资源
最近更新 更多