首页 > 解决方案 > 在线程内将项目添加到 NSMutableArray

问题描述

我想用线程扫描照片库,当我的应用程序逻辑正常时,我想将其添加PHAssetfinalarray

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);
    });
}

arrayOfArrays是数组的数组PHAsset

我的代码工作正常,但有时我会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

标签: iosobjective-ciphone

解决方案


如果您有多个线程更新一个属性,您必须同步它们的访问。您可以使用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 .requestImageDataForAsset

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


推荐阅读