【问题标题】:attempt to insert nil object from objects尝试从对象中插入 nil 对象
【发布时间】:2023-03-29 23:29:01
【问题描述】:

我有以下错误

-[__NSPlaceholderArray initWithObjects:count:]: 尝试从 objects[1539] 中插入 nil 对象

有时会在屏幕上点击几次,因为代码很少,所以所有代码都粘贴在下面

@interface ViewController ()
@property (nonatomic,weak) NSTimer *timer;
@property (nonatomic,strong)NSMutableArray * testArray;
@property (nonatomic,strong) dispatch_queue_t queue1;
@property (nonatomic,strong) dispatch_queue_t queue2;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.testArray = [NSMutableArray array];
    _queue1 = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    _queue2 = dispatch_queue_create("test",DISPATCH_QUEUE_SERIAL);
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(addObjectforArray) userInfo:nil repeats:YES];
    [timer fire];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
       dispatch_async(_queue2, ^{
           NSLog(@"touchesBeganThread:%@",[NSThread currentThread]);
           NSArray * testTempArray = [NSArray arrayWithArray:self.testArray];
           for (UIView *view in testTempArray) {
               NSLog(@"%@",view);
           }

    });
}

- (void)addObjectforArray{
    dispatch_async(_queue1, ^{
        NSLog(@"addObjectThread:%@",[NSThread currentThread]);
        [self.testArray addObject:[[UIView alloc]init]];
    });
}

我不明白为什么会这样,如果我把_queue1改为DISPATCH_QUEUE_SERIAL,就正常了。

我该如何理解这个问题?如果有人能提供一些启示,那就太好了。

【问题讨论】:

    标签: ios objective-c crash


    【解决方案1】:

    您的代码中存在多个问题。它们会随机导致各种错误。

    1. UIView 应该使用dispatch_get_main_queue() 在主线程中创建。 https://developer.apple.com/documentation/uikit

      在大多数情况下,只使用应用程序的主线程或主调度队列中的 UIKit 类。此限制适用于派生自的类 UIResponder 或涉及以任何方式操纵您应用的用户界面。

    2. 属性testArraynonatomic,但在两个线程中访问。该属性应为atomic。它目前运行良好,但它很脆弱。如果将来testArray 发生变异,应用会随机崩溃。

    3. NSArray 不是线程安全的。多线程访问时应加锁或通过其他方式保护。

    4. 正如@Nirmalsinh 所指出的,dispatch_async 是多余的(实际上是有害的)。

    我不确定您是大大简化了代码还是只是为了测试某些内容。如果您不做长期工作,您可能希望在dispatch_async 中使用dispatch_get_main_queue()。它会让你免于很多麻烦。

    【讨论】:

      【解决方案2】:

      您似乎正在向数组中插入 nil 值。您不能将 nil 添加到数组或字典中。

      - (void)addObjectforArray{
              NSLog(@"addObjectThread:%@",[NSThread currentThread]);
              UIView *view = [[UIView alloc] init];
              if(view != nil)
                  [self.testArray addObject:view];
      }
      

      方法中不需要使用队列。您已经在使用 NSTimer。

      尝试检查以上。它会帮助你。

      【讨论】:

      • -[UIView init] 永远不会返回 nil
      • 你需要分配它。 [[UIView alloc]init]
      猜你喜欢
      • 2017-12-16
      • 2020-11-08
      • 2012-08-09
      • 2016-05-23
      • 1970-01-01
      • 2014-08-27
      • 2014-07-16
      • 2012-10-30
      • 1970-01-01
      相关资源
      最近更新 更多