【问题标题】:Objective-C: How do I modify the NSMutableArray in a different thread safely?Objective-C:如何安全地在不同的线程中修改 NSMutableArray?
【发布时间】:2016-07-27 02:46:10
【问题描述】:

我声明了一个原子 NSMutableArray 来保存对象

@property (atomic, strong) NSMutableArray *list;
@synthesize list;

然后我使用线程来保存对象,例如:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ // writing files into the disk in background
    // do something..

    [weakSelf.list addObject:object]; // add object at the end of the list

    if (!weakSelf.threadCreateFlag) {
        NSInvocationOperation *newoperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(createThreadMethod) object:nil]; // create thread to remove from the array

        [weakSelf.serailQueue addOperation:newoperation];
    }
});

我正在尝试读取索引 0 处的对象并将其从数组中删除

- (void)createThreadMethod {

self.threadCreateFlag = YES;

do {
    NSLog(@"loop");
    @autoreleasepool {

        NSDictionary *object = (NSDictionary *)[self.list objectAtIndex:0];
        [self.list removeObjectAtIndex:0];

        // doing something...
    }
} while(self.list.count > 0);

self.photoSavingLock = NO;
}

我遇到了一个问题 - 有时,数组包含对象 0x0,我的应用程序会崩溃。 我对此进行了一些研究,我认为是因为removeObjectAtIndex 不是线程安全的。所以我试图在读取/删除和添加功能周围添加一个全局@property (atomic, strong) NSLock *lock。 但是这次我得到了[NSLock deadlock]。

使这个场景线程安全的正确方法是什么?

【问题讨论】:

标签: ios objective-c multithreading nsmutablearray


【解决方案1】:

使事情线程安全的最简单的两种方法是使用@synchronized 或将事情分派到串行队列。

我的最大效率策略:拥有一个可变数组和一个不可变数组。当你想修改数组时:

- (void)modifyArray {
    @synchronized (self) {
        if (_mutableArray == nil) {
            _mutableArray = [(_immutableArray ?: @[]) mutableCopy];
            _immutableArray = nil;
        }
        // Modify the mutable array. 
    }
}

- (NSArray*)immutableArray {
    @synchronized (self) {
        if (_mutableArray != nil) {
            _immutableArray = [_mutableArray copy];
            _mutableArray = nil;
        }
        return _immutableArray;
    }
}

显然,您将获得 immutableArray一次,调用擦除列表,然后遍历 immutableArray。或者有一个方法 - (NSDictionary*)removeFirstElement 删除第一个元素并返回 nil 如果没有其他内容要删除。

【讨论】:

    猜你喜欢
    • 2012-08-19
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2013-09-28
    相关资源
    最近更新 更多