【问题标题】:Any danger using performselector in objective-c?在objective-c中使用performselector有什么危险吗?
【发布时间】:2016-10-13 07:30:23
【问题描述】:

我被 Crashlytics 上的崩溃卡住了几天,上面写着:

libobjc.A.dylib

objc_msgSend

我设法指出了这次崩溃的原因:__NSThreadPerformPerform

在堆栈上稍作搜索,它似乎与 performSelector:withObject:afterDelay:

相关联

我的代码一直提到延迟0。我使用这种方法来调用我们在 iOS 中可以称为“函子”的东西,方法是从我从枚举状态访问的字符串数组动态地重新创建选择器。

基本上这是我到目前为止所获得的所有信息,我了解到 afterDelay: 使您的呼叫延迟到下一个 RunLoop。它是否也适用于 performSelector:withObject: 或 afterDelay: 将某些内容添加到导致此问题的方法中?

最后,真正的问题:

performSelector:withObject:afterDelay: 是制作函子的好方法,还是这样使用它很危险,我应该采用其他方式吗?

提前致谢,

【问题讨论】:

  • 与 Objective-C 中的所有内容一样,performSelector 对开发人员来说很容易出错,并且可能导致大量 objc_msgSend 崩溃。这个错误主要是在错误的对象上调用选择器引起的(你应该调用的对象可能被释放了)
  • 是的,但是我知道这种东西,并且在使用指针时崩溃是相当“正常的方式”。但是在这里我看不到在我调用它的那一刻我的对象是如何被释放的,即使它等到下一个 runLoop 如果我只使用 IBOutlet 留在同一个 ViewController 上,我的对象如何被释放。这可能是由任何“内存警告”问题引起的吗? ARC 应该为这种情况保留重要资源,不是吗?
  • 尝试为您的调试方案启用僵尸模式。复制崩溃,它应该会告诉你出了什么问题。
  • 嗯,真正的问题是我无法复制崩溃,直到现在我才在我的 Crashlytics 报告中看到它,当我试图以任何方式复制它并且做了非常糟糕的事情时对我的应用程序来说,它从未发生过。我将尝试启用僵尸,也许它会在我使用 Xcode 的基本调试器无法做到的地方崩溃。

标签: ios objective-c performselector


【解决方案1】:

不要只是假设你的对象仍然存在并且可以执行选择器。之前测试一下!

if ([someObject respondsToSelector:@selector(someSelector)]) {
   [someObject performSelector:@selector(someSelector) withObject:nil];
}

【讨论】:

  • 非常感谢,我不知道我怎么忘了这个哈哈。
  • 好吧,不存在的对象(变量为nil)不是问题。对象不执行选择器将是一个问题,但这表明该对象不是程序员认为的那样。
猜你喜欢
  • 1970-01-01
  • 2011-07-17
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
相关资源
最近更新 更多