Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios A64:objc_msgSend在PerformSelect:withObject:works时崩溃_Ios_Objective C_Ipad_32bit 64bit - Fatal编程技术网

Ios A64:objc_msgSend在PerformSelect:withObject:works时崩溃

Ios A64:objc_msgSend在PerformSelect:withObject:works时崩溃,ios,objective-c,ipad,32bit-64bit,Ios,Objective C,Ipad,32bit 64bit,我正在尝试调试iOS上的崩溃,该崩溃在支持。特别是使用/SoC的iPad。同样的代码在任何32位iPad上运行时也不会崩溃(如果我将构建限制为仅32位架构,然后在支持64位的iPad上运行32位代码,则同样适用) 崩溃报告为一个EXC\u BAD\u ACCESS,触发它的代码没有什么特别之处: if (object && [self respondsToSelector:addSelector]) { objc_msgSend(self, addSelector, ob

我正在尝试调试iOS上的崩溃,该崩溃在支持。特别是使用/SoC的iPad。同样的代码在任何32位iPad上运行时也不会崩溃(如果我将构建限制为仅32位架构,然后在支持64位的iPad上运行32位代码,则同样适用)

崩溃报告为一个
EXC\u BAD\u ACCESS
,触发它的代码没有什么特别之处:

if (object && [self respondsToSelector:addSelector]) {
    objc_msgSend(self, addSelector, object);                  //EXC_BAD_ACCESS on A64 devices!
    //[self performSelector:addSelector withObject:object];   //no crash  
}
有问题的行是
objc_msgSend(self、addSelector、object)。第一个令人困惑的部分是,如果我用
[self-performSelector:addSelector withObject:object]替换这一行,一切正常(尽管它给我留下了一个令人讨厌的“PerformSelector可能导致泄漏…”警告)。除非我完全误解了某些内容,
objc\u msgSend
performSelector:withObject:
在这种情况下基本上应该是等效的

那么,为什么一个会崩溃(而且只有在使用A64时),而另一个不会呢

下一个令人困惑的问题是,当崩溃发生时,尝试调试崩溃。
self
object
都是
NSManagedObject
实例,我可以在调试器中观察到它们都是有效的对象。然而,例外情况总是报告为:

-[NSManagedObjectContext实体]:发送到实例0x的无法识别的选择器…

该调用显示为源自
CoreData
的内部,我无法给出任何合理的解释,尤其是作为从32位架构/构建切换到64位架构/构建的副作用

有没有关于什么会导致这种问题的想法?或者我应该只使用
性能选择器:withObject:
并感到快乐吗

触发它的代码也没有什么特别奇妙的地方

正如您所发现的,直接调用
objc\u msgSend()
非常花哨,而且很难正确执行

第一个令人困惑的部分是,如果我用[self-performSelector:addSelector withObject:object];,一切正常

是的。因为这些不一样

objc\u msgSend*
有几种风格,您需要根据返回类型和处理器选择正确的。具体来说,有三个版本:

  • objc\u msgSend\u fpret
    ——用于浮点返回类型(适用于OS X;我还没有查找它是否适用于64位ARM)
  • objc\u msgSend\u stretc
    ——用于结构返回类型(如
    CGPoint
  • objc\u msgSend
    ——其他退货类型
我记不清在所有处理器上是否都是这样。有些处理器处理“大”结构与处理“小”结构不同。调用约定都是特定于处理器的,这就是为什么您只能在一个处理器上看到它。还记得我说过直接调用
objc\u msgSend()
很花哨吗


使用此函数调用任意选择器的事实表明,其中一些选择器具有结构或浮点返回,在这种情况下,事情将位于错误的寄存器中,并且事情将完全偏离方向

有关这方面的更多讨论,请参阅

有没有关于什么会导致这种问题的想法?或者我应该只选择那个性能选择器:with object:并快乐吗


正如警告所说,
performSelector:
可能会泄漏,因为ARC不知道如何对其进行内存管理。解决方案是重新编写,使用块而不是选择器。如果必须使用选择器,并且确定此处调用的选择器都不会返回对象,请参阅以了解如何使警告静音。如果这些可以返回对象,那么您需要确保它们上不会有额外的保留,这只是一个兔子洞,您可能不应该进入这个洞(或者至少应该提出一个新问题)。

您使用的是SQLite db类型吗?@WarrenBurton-是,应用程序将
NSSQLiteStoreType
与CoreData一起使用。什么是
addSelector
?如果可能,您可以更改为
NSBinaryStoreType
并查看崩溃是否再现。不是说这是一个长期的解决方案。只是想看看SQLite引擎中是否有故障。@Cy-4AH-它有些易变,但是
addSelector
将始终是一种“CoreDataGeneratedAccessor”方法,用于处理“对多”关系,适用于正在处理的
实体和
对象。“使用此函数调用任意选择器的事实表明,其中一些选择器具有结构或浮点返回“-返回类型始终为
void
,这意味着
objc_msgSend
是正确的API使用方法?如果是,您可能不会只在一个平台上发生崩溃。它们是否都只接受一个没有varargs的参数?我会尝试将所有可能的选择器放在静态代码中构建并编译它,然后查看程序集(“助手”中的“汇编程序视图”)。确保它们都编译为完全相同的设置和函数调用。正如我所说的,objc_msgSend非常复杂,而且是特定于平台的。很难把它弄对。