gpt4 book ai didi

ios - 有关如何从所需设备捕获 "attempt to insert nil object"的建议

转载 作者:可可西里 更新时间:2023-11-01 06:22:01 26 4
gpt4 key购买 nike

这是一种情况:Hockeyapp 和 testflight 时不时地提示我

"attempting to insert nil object"

在可变字典/数组中。我知道正确的做法是始终检查 nil,当它有意义时我会这样做。我们的测试人员无法捕捉到这些崩溃,但 AppStore 用户显然可以。

我的猜测是有时服务器在不应该返回 NSNulls 时返回。因此,不要在这个庞大的项目中到处插入 nil 检查,我的想法是为测试人员创建一个单独的目标,并对集合类使用方法调配。比如,我将用我的 swizzled_insertObject:atIndex 替换 insertObject:atIndex,如果对象实际上是 nil,我会在它崩溃之前记录/显示描述性报告。

问题是我不能对 __NSPlaceholderDictionary__NSArrayM 使用 swizzling(只是因为我不能在私有(private)类上创建类别),这让我很难过。

所以基本上我是在征求有关如何捕捉那些讨厌的罕见崩溃的建议。我想到的一种解决方案是使用 try-catch block ,我知道它们在 Objective-c 中很昂贵,所以我不会在生产中使用它们,仅供测试人员使用。但是被 try-catche 包围的方法 - 被 #ifdef-#endif-s 包围的方法将消除代码的所有可读性。所以我正在寻找一个更优雅的解决方案。谢谢。

更新:不幸的是,堆栈跟踪不是很有描述性,这是我得到的

Exception Type:  SIGABRT
Exception Codes: #0 at 0x3a378350
Crashed Thread: 0

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'

Last Exception Backtrace:
0 CoreFoundation 0x321522a3 <redacted> + 163
1 libobjc.A.dylib 0x39e7a97f _objc_exception_throw + 31
2 CoreFoundation 0x320a355f <redacted> + 135
3 CoreFoundation 0x320da0d3 <redacted> + 51
....

最佳答案

您无需添加类别即可进行方法调配。我能够通过方法 swizzling initWithObjects:forKeys:count: 并在原始方法调用周围放置一个 try/catch 来隔离这样的崩溃。最后我在 catch 部分添加了一个断点。这允许我中断并返回堆栈到使用 nil 值的位置。此代码添加在我的 AppDelegate.m 的顶部:

#import <objc/runtime.h>
#import <objc/message.h>
static id safe_initWithObjects(id self, SEL _cmd, const id objects[], const id <NSCopying> keys[], NSUInteger count) {
id orignialResult = nil;
@try {
orignialResult = objc_msgSend(self, @selector(safe_initWithObjects:forKeys:count:), objects, keys, count);
}
@catch (NSException *exception) {
NSLog(@"BUSTED!"); // put breakpoint here
}

return orignialResult;
}

然后在我的应用中完成启动方法:

Class target = NSClassFromString(@"__NSPlaceholderDictionary");
class_addMethod(target, @selector(safe_initWithObjects:forKeys:count:), (IMP)&safe_initWithObjects, "@@:**L");

Method m1 = class_getInstanceMethod(target, @selector(safe_initWithObjects:forKeys:count:));
Method m2 = class_getInstanceMethod(target, @selector(initWithObjects:forKeys:count:));
method_exchangeImplementations(m1, m2);

关于ios - 有关如何从所需设备捕获 "attempt to insert nil object"的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17346046/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com