不可能NSInvalidArgumentException - 尝试插入nil对象?

时间:2018-02-23 13:10:37

标签: ios objective-c crash nsmutablearray

我收到NSInvalidArgumentException 我的代码中第1148行的Crashlytcs发现*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil异常,向您显示我的代码的1147-1149行:

if(snapshot.stickerInfoForAnalitycs) {
    [self.usedStickers addObject:snapshot.stickerInfoForAnalitycs];//1148 line
}

self.usedStickersNSMutableArray

这怎么可能? (我知道crashlitycs有可能显示错误的行,但这不太可能,因为这个崩溃出现在应用程序的9.20版本中,而在9.24版本中它仍然在1148行中。)

UPD:stickerInfoForAnalitycs是一个NSString *属性,没有getter / setter覆盖。声明为@property (nonatomic) NSString * stickerInfoForAnalitycs;

3 个答案:

答案 0 :(得分:1)

根据您提供的代码段,在snapshot.stickerInfoForAnalitycs添加nil之前,您确保NSMutableArray不是-[__NSArrayM insertObject:atIndex:]

错误消息self.usedStickers清楚地表明nil不是__NSArrayM,实际上是NSMutableArray的实例,它是snapshot.stickerInfoForAnalitycs类的私有子类簇。这是正常的。

所以,我可以提出最有可能发生问题的情况 - 另一个线程在if语句中测试后立即修改stickerInfoForAnalytics值,但在插入之前数组。

因此,我建议检查其他线程是否不会修改stickerInfoForAnalitycs值。使用启用的线程清理程序运行代码可能会有所帮助。有关详细信息,请参阅https://developer.apple.com/documentation/code_diagnostics/thread_sanitizer/enabling_the_thread_sanitizer。请注意,线程清理程序是一个非常好的工具,但它仍然无法检测到每个可能的问题。因此,您仍然需要阅读代码并查找stickerInfoForAnalitycs值已更改的所有位置。

另一种可能性是,例如,nil方法的自定义实现可能会在首次访问时返回正确的值,但在第二次访问时会返回{{1}}。我认为这个选项不太可能。

答案 1 :(得分:0)

访问属性时,最好将一个值赋给局部变量,以确保在检查属性和使用它的时间之间不会发生变异。或者,您可以使用@synchronized块来确保属性的所有访问都是互斥的。

从根本上说,你假设价值不可能是nil是错误的,因为你得到了两次不同的价值。

NSString *stickerInfoForAnalitycs = snapshot.stickerInfoForAnalitycs;
if (stickerInfoForAnalitycs != nil) {
    [self.usedStickers addObject:stickerInfoForAnalitycs];//1148 line
}

使用此代码,实际上无法获得NSInvalidArgumentException

答案 2 :(得分:-4)

你不妨试试这个:

if(snapshot.stickerInfoForAnalitycs) {
     @synchronized(self.usedStickers) {
        [self.usedStickers addObject:snapshot.stickerInfoForAnalitycs];//1148 line 
     }
}