尝试从对象插入nil对象

时间:2017-08-09 10:49:55

标签: ios objective-c crash

我有以下错误

  

- [__ NSPlaceholderArray initWithObjects:count:]:尝试从对象中插入nil对象[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 ,则会变得正常。

我如何理解这个问题?如果有人可以发光,那就太好了。

2 个答案:

答案 0 :(得分:0)

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

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

      

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

  2. 属性testArraynonatomic,但是可以通过两个线程访问。该属性应为atomic。它此刻运行良好,但它很脆弱。如果将来testArray发生变异,应用程序将随机崩溃。

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

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

  5. 我不确定您是否大量简化了代码或仅测试某些内容。如果您没有进行长时间的工作,则可能需要在dispatch_get_main_queue()中使用dispatch_async。这样可以避免很多麻烦。

答案 1 :(得分:-1)

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

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

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

尝试检查以上内容。它会对你有所帮助。