【问题标题】:Is there a method that always gets called right after didSelectRowAtIndexPath?是否有一种方法总是在 didSelectRowAtIndexPath 之后立即被调用?
【发布时间】:2012-09-13 04:51:26
【问题描述】:

我正在开发一个 iPad 应用程序,其中有一个表格视图。当用户选择表格中的一行时,我使用didSelectRowAtIndexPath 打开一个弹出框。当我尝试使用某个按钮时,我收到一条错误消息,说“消息已发送到已释放的实例”。我最初虽然错误是由弹出框抛出的(在它的viewDidLoad 或其他东西中),所以我在其中设置了一个断点并单步执行代码。令我惊讶的是,我能够在我的表格视图上一直加载弹出框和didSelectRowAtIndexPath 的其余部分(实际上只涉及退出一些 if 块)。然后,当我在自动生成的代码中执行几个步骤时抛出错误,该代码没有出现在我的任何类文件中(看起来像 0x0010d71d <+1164> mov 0x6...)。

所以,我的问题是,如何找到引发此错误的位置?是否有另一种在 didSelectRowAtIndexPath 之后自动运行的方法可能会在某处搞砸?

【问题讨论】:

  • 它会告诉你实例属于哪条消息和哪个类吗?
  • 分配弹出框时是否使用autorelease
  • @Phillip Mills:意思是-[CFString release]。我自己从来没有明确使用过 CFString,所以它一定来自其他东西。也许我会在谷歌上搜索一下,看看是否有任何帮助。
  • @jere:我正在使用performSegueWithIdentifier-(void) prepareForSegue 来显示我的弹出框,控制器是我的视图控制器的@property,所以我认为这意味着它应该是自动释放的,正确的?我对使用 Mac 还是很陌生,所以很多这些东西仍然让我有点头疼。我所拥有的大部分内容都是从我在 SO 和 youtube 上找到的教程中复制而来的,但我通常不知道为什么会这样设置,而且其中一些概念对我来说仍然有点模糊。

标签: ios uitableview uipopover


【解决方案1】:

在您的 DEBUG 构建中启用 NSZombieEnabled(请参阅 How do I set up NSZombieEnabled in Xcode 4?)以定位您正在访问的已被释放/释放的对象的实例。

另外,考虑将您的项目升级到 ARC,这可能会解决此类内存管理问题。

【讨论】:

  • 我已经启用了 NSZombieEnabled,当我进行分析时,我得到的唯一结果是弹出窗口中单元格上的一堆“在初始化期间存储的值永远不会被读取”(这也是从 UITableViewController 构建)。我不熟悉这条消息,所以我现在正在查找它,看看它是否有帮助。
  • 编辑:它不在我的弹出框的单元格上,它在我原始视图cellForRowAtIndexPath 的单元格上。
  • 所以现在在我的cellForRowAtIndexPath 中我有:static NSString *CellIdentifier = @"Cell"; MyCell *cell = (MyCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell = [[[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; //plus some stuff about setting labels from an array for indexPath.row 据我所知,我正在为cell 进行两次分配。这部分我几乎是直接从教程中复制而来的,所以不确定它到底做了什么,或者我需要摆脱哪个,或者如何修复它。
【解决方案2】:

好的,大家的回复让我找到了malloc error -[CFString release],这帮助我发现我的弹出框中有一个字符串,我在viewDidLoad by 中分配了一个字符串

myString = [NSMutableString stringWithString:[myGlobalFunctionClass getMyString]];

由于我以这种方式分配它,它被设置为自动释放。问题是我在viewWillAppear 中明确地是[myString release];myString = nil;。删除 release=nil 部分清除了我的错误。

为了回答我发布的实际问题,我相信 autorelease 直到模拟器实际尝试显示弹出框(它将在 didSelectRowAtIndexPath 之后运行)才会触发。因为这发生在我在viewWillAppear 中明确地[myString release] 之后,它试图autorelease 一些不再存在的东西。重申一下,正确的做法是在最后添加autorelease,而不是在我的代码中的任何位置添加[myString release]

有人可以验证这是否正确吗?正如我在我的 cmets 中提到的,我对 iOS 开发还是很陌生。在这个项目结束时,我有一种感觉,我将能够回到我在其中所做的第一件事,并在更有效地和更符合最佳实践方面进行数十项改进。

【讨论】:

  • 是的,[myString release] 对自动释放的对象是一个巨大的禁忌。升级到 ARC,有一个 WWDC 2011 视频,介绍 ARC 是什么以及如何更新您的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
相关资源
最近更新 更多