【问题标题】:iPhone message sent to deallocated instanceiPhone 消息发送到解除分配的实例
【发布时间】:2014-05-11 14:47:16
【问题描述】:

当我的 UITableviewContrller 出现时快速触摸文本字段时,我遇到了一个导致崩溃的奇怪问题。 它并不总是发生。大约 10 次测试的 2 次崩溃。 以前可以正常使用,但现在不知道为什么有时会崩溃。

iOS7.1 上的 iPhone4。 崩溃消息。它在 OrderTableViewController 中崩溃。在崩溃之前,我检查了 retainCount 是否为 1,所以我不知道这是怎么发生的。我不知道为什么它被释放了。

2014-04-01 09:35:57.628 [17027:60b] *** -[OrderTableViewController respondsToSelector:]: message sent to deallocated instance 0x17fef520

这是我推送 viewController 的代码。 我相信这是正确的。我一直在使用它。

OrderTableViewController *orderViewController = [[OrderTableViewController alloc] initWithNibName:@"OrderTableViewController" bundle:nil];
    orderViewController.hidesBottomBarWhenPushed = YES;

    [self pushViewController:orderViewController animated:YES];
    [orderViewController release];

我没有将文本字段声明为保留。我不确定这是否是问题所在。 UITextField *uname; UITextField *utel;

uname = [[UITextField alloc] initWithFrame:CGRectMake(180, 8, 120, 30)];
uname.BorderStyle=UITextBorderStyleRoundedRect;
uname.keyboardType=UIKeyboardTypeNamePhonePad;
uname.delegate=self;


utel = [[UITextField alloc] initWithFrame:CGRectMake(180-40, 8, 120+40, 30)];
utel.BorderStyle=UITextBorderStyleRoundedRect;
utel.delegate=self;
utel.keyboardType=UIKeyboardTypeNumberPad;

- (void)dealloc {
[uname release];uname=nil;
[utel release];utel =nil;
[super dealloc];
}

我尝试使用僵尸模板按​​仪器配置文件,但找不到有用的东西。 这里有问题。 1.对这个问题有什么想法吗? 2. 如何解决此类问题。我尝试删除 [orderViewController release] 的代码;并且retainCount 变为2,20 次测试似乎还可以。但是,它会导致内存泄漏。如何减少这种泄漏问题。当我不需要它时,我可以在导航控制器中释放它吗?我知道这更复杂,但我不知道更好的解决方法。 表单消息 crash ,似乎与 OrderViewController 过度释放有关,但我找不到问题所在。是否有其他问题导致错误消息? 感谢您的帮助。

【问题讨论】:

  • 只是为了验证,你没有使用arc,对吗?
  • 不,我没有使用 arc。
  • 我可以询问您为什么不使用 ARC 吗???你知道提交到应用商店的应用必须使用 ARC???
  • @Popeye 应用商店不在乎你是否使用 ARC。 (虽然我同意,但几乎每个人都应该使用它)
  • @jrturton 是的,你是完全正确的

标签: ios objective-c memory-management


【解决方案1】:
  • 不要使用retainCount。例如,它永远不会返回 0。

  • 问题是您的委托在视图控制器完成处理之前就被释放了。您可以通过在dealloc 中将代理设置为nil 来解决这个问题,但这可能也不正确,因为它表明您的视图控制器将比它委托行为的东西寿命更长也做出决定。

  • 您的dealloc 方法错误;在非 ARC 中,您必须致电 [super dealloc];

  • 您应该使用 ARC

【讨论】:

  • 谢谢,bbum。你的回答解决了我的另一个问题。但是,我不确定是不是这个问题的delegate to nil的问题(事实上,我只是尝试过,但它仍然崩溃。),因为它只是在OrderViewController出现期间崩溃(而不是消失。)。 OrderViewController 应该处于活动状态。然后我按下 OrderViewController 中的文本字段,然后它崩溃了。并且 OrderViewController 不是其他 View 的委托视图。它只是 OrderTableView 中 textfield 的代表。将代码更改为 ARC 可以解决此问题吗?
【解决方案2】:

首先检查以确保您没有直接在其上调用 dealloc。

然后尝试运行 Xcode Analyzer,因为它可能会为您找到问题。

然后尝试启用Exception Breakpoint 并查看它是否在有用的地方停止。

如果这些不起作用,请尝试在 OrderTableViewController 上实现 -retain-release 方法,然后在每个方法中放置断点。然后,您可以跟踪谁在保留和释放它,您应该能够找到谁在过度释放它。

- (id)retain
{
    return [super retain];
}

-(oneway void)release
{
    [super release];
}

【讨论】:

  • 更容易在分配工具中打开track reference counts,然后使用它来检查保留/释放。覆盖 retain/release 上的断点有效,但相对而言确实很乏味。
  • 是的,这很好。这是另一个非常有效的选择。我也想过提到乐器。但是,在某些情况下,我喜欢保留释放断点方法,因为它是一种更熟悉的方法,能够查看调用堆栈并检查变量的值。另外,我认为它提供了一个示例,说明了在不使用现有工具解决问题的情况下创造性地思考调试的方法。
  • 是的;因此投票赞成。 :) 有趣的运动;使用自省类能够自动转储这些方法中的回溯。我经常使用这种技术来追踪难以通过 Instruments 分析的代码中难以发现的内存问题。如果您实现行为不端的类的子类并且只实例化一次或两次,它会大大降低日志记录噪音。对于超级棘手的奖励积分,您可以在线程/堆栈达到峰值,以不打印您知道不存在问题的回溯。
【解决方案3】:

你应该 nil 委托。也就是说,uname.delegate = nil 在 dealloc 中。

【讨论】:

    【解决方案4】:

    问题很可能是您在导航控制器有机会声明所有权之前释放了您的视图控制器。有两种解决方法:

    • 将控制器推送到导航控制器后释放控制器

    • 在推动控制器之前自动释放控制器。如果您这样做,活动的 NSAutoreleasePool(您无需担心)将负责稍后释放您的控制器。

    [orderViewController autorelease];

    【讨论】:

    • 那是一段不错的代码,你为什么要这样做??? -1,因为如果您在答案中提供解释而不是 cmets,则对它的解释为零,我将删除我的 -1
    • 正如我所承诺的,我已经删除了我的 -1
    • pushViewController:.. 保留控制器。
    猜你喜欢
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多