将项目添加到线程内的 NSMutableArray

add item to NSMutableArray inside a thread

我想用线程扫描照片库,当我的应用程序逻辑正常时我想将 PHAsset 添加到 finalarray:

NSMutableArray <PHAsset *> *finalarray = [[NSMutableArray alloc] init];

for (NSMutableArray *photoArray in arrayOfArrays) {
    dispatch_group_enter(aGroup);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        for (PHAsset *asset in photoArray) {
            [[PHImageManager defaultManager] requestImageDataForAsset:asset
                                                              options:options
                                                        resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {

                //Make some logic

                if (logic) {
                    [finalarray addObject:asset];
                }
            }];
        }
        dispatch_group_leave(aGroup);
    });
}

arrayOfArraysPHAsset.

数组的数组

我的代码工作正常,但有时我会遇到 SIGABRT 崩溃,并且我在代码控制台中得到以下登录信息:

malloc: Incorrect checksum for freed object 0x1206d5968: probably modified after being freed.
Corrupt value: 0x100017580
malloc: *** set a breakpoint in malloc_error_break to debug
malloc: Incorrect checksum for freed object 0x1206d5968: probably modified after being freed.
Corrupt value: 0x100017580

如果您有多个线程更新 属性,您必须同步它们的访问。您可以使用 NSLock:

NSMutableArray <PHAsset *> *finalarray = [[NSMutableArray alloc] init];
NSLock *lock = [[NSLock alloc] init];

for (NSMutableArray *photoArray in arrayOfArrays) {
    dispatch_group_enter(aGroup);
    for (PHAsset *asset in photoArray) {
        [[PHImageManager defaultManager] requestImageDataForAsset:asset
                                                          options:options
                                                    resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {

            //Make some logic

            if (logic) {
                [lock lock];
                [finalarray addObject:asset];
                [lock unlock];
                dispatch_group_leave(aGroup);
            }
        }];
    }
}

或者您可以使用 GCD 队列:

NSMutableArray <PHAsset *> *finalarray = [[NSMutableArray alloc] init];
dispatch_queue_t queue = dispatch_queue_create("...", NULL);

for (NSMutableArray *photoArray in arrayOfArrays) {
    dispatch_group_enter(aGroup);
    for (PHAsset *asset in photoArray) {
        [[PHImageManager defaultManager] requestImageDataForAsset:asset
                                                          options:options
                                                    resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {

            //Make some logic

            if (logic) {
                dispatch_async(queue, ^{
                    [finalarray addObject:asset];
                    dispatch_group_leave(aGroup);
                });
            }
        }];
    }
}

注意,上面我假设你正在异步获取图像,在这种情况下你不需要使用全局队列,但你需要确保调用 dispatch_group_leave inside requestImageDataForAsset.

但是,无论如何,请确保在从多个线程访问属性时同步您的访问(使用 GCD 队列或某些锁)。