【问题标题】:impossible NSInvalidArgumentException - attempt to insert nil object?不可能的 NSInvalidArgumentException - 尝试插入 nil 对象?
【发布时间】:2018-02-23 13:10:37
【问题描述】:

我收到 NSInvalidArgumentException *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil 我的代码中第 1148 行的 Crashlytcs 异常,向您展示了我的代码的 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;

【问题讨论】:

  • snapshot.stickerInfoForAnalitycsnil
  • 消息清楚地表明snapshot.stickerInfoForAnalitycs 为零。确保总有一个值
  • 好吧,我刚读了整个 sn-p,虽然我不是 objC 程序员,但if(snapshot.stickerInfoForAnalitycs) { 测试应该确保它不是 nil... 对吧?
  • @luk2302 但 if(snapshot.stickerInfoForAnalitycs) 用于检查这种情况
  • @passingnil - 好的,也许可以这样尝试:NSString *s = [snapshot.stickerInfoForAnalitycs copy]; if (s) { ... } 这也将允许您在此处放置一个断点以检查发生了什么。

标签: ios objective-c crash nsmutablearray


【解决方案1】:

根据您提供的代码 sn-p,在将 snapshot.stickerInfoForAnalitycs 添加到 NSMutableArray 之前,您要确保 snapshot.stickerInfoForAnalitycs 不是 nil

错误消息-[__NSArrayM insertObject:atIndex:] 清楚地表明self.usedStickers 不是nil,实际上是__NSArrayM 的一个实例,它是NSMutableArray 类簇的私有子类。这正如预期的那样顺利。

所以,我可以想出最有可能出现问题的场景——另一个线程在if 语句中测试它之后,但在它被插入数组之前修改了snapshot.stickerInfoForAnalitycs 值。

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

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

【讨论】:

  • 这个问题出现了 192K 次和 100K+ 用户受此影响,您是否认为在执行 [self.usedStickers addObject:snapshot.stickerInfoForAnalitycs] 行之前的所有情况下,正在修改 snapshot.stickerInfoForAnalitycs来自其他线程?
  • @passingnil,那我觉得很奇怪。我不希望你的情况出现这个根本原因,但仍然值得仔细检查。根据我的最后建议,如果您有此属性的自定义 getter,请确保 stickerInfoForAnalitycs 实现是正确的。
  • stickerInfoForAnalitycs - 是一个简单的 NSString * 属性,没有 getter/setter 覆盖。 @property (nonatomic) NSString *stickerInfoForAnalitycs;是该属性的声明
  • 那么我看到的唯一可能就是线程问题。 @nithinbhaktha 的建议可能会有所帮助,但正如我在对他的回答的评论中提到的那样,您需要在使用 usedStickers 的其他代码中执行类似的更改。如果是这种情况 - 我对线程分析器的建议也将有助于检测问题。
  • 感谢您的帮助,但实际上织物显示的线条有误。
【解决方案2】:

访问属性时,最好的做法是为局部变量赋值,以确保属性在检查和使用期间不会发生变化。或者,您可以使用@synchronized 块来确保对属性的所有访问都是互斥的。

从根本上说,您认为该值不可能为 nil 的假设是错误的,因为您两次获得该值。

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

使用此代码,确实不可能获得NSInvalidArgumentException

【讨论】:

    【解决方案3】:

    你不妨试试这个:

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

    【讨论】:

    • 可能有意义,但您还需要在修改或查询此数组内容的其他代码中实现对self.usedStickers 的同步访问
    • usedStickers 的使用不是错误的来源,此代码不保护对任何内容的访问。
    猜你喜欢
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2017-12-16
    • 2012-08-09
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多