ios - 尝试从对象中插入 nil 对象

标签 ios objective-c crash

我有以下错误

-[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[1539]

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

@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,它就正常了。

如何理解这个问题?如果有人能阐明一些观点,那就太好了。

最佳答案

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

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

    For the most part, use UIKit classes only from your app’s main thread or main dispatch queue. This restriction applies to classes derived from UIResponder or that involve manipulating your app’s user interface in any way.

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

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

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

我不确定您是否已经大大简化了您的代码或只是为了测试某些东西。如果您不进行长时间运行的工作,则可能需要在 dispatch_async 中使用 dispatch_get_main_queue()。它将为您省去很多麻烦。

关于ios - 尝试从对象中插入 nil 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45588589/

相关文章:

android - 下拉菜单在移动设备上不起作用

objective-c - 如何在 NSTableView 中重用单元格?

iphone - 我的类应该转换为核心数据管理对象,还是核心数据管理对象

crash - 应用程序关闭时 CLI DLL 中无法解释的崩溃

iphone - 使用ios 4创建的应用在ios 6中崩溃且未安装

ios - 几分钟后在后台套接字上监听SIGSTOP

iphone - 访问 iOS 中的设置应用程序

IOS - 工具栏内的 UITextField 问题

ios - 从 Objective-C 转换为 Swift (TestFlight)

iPhone 在导航 Controller 动画期间崩溃,我有什么选择?