ios - 在线程内将项目添加到 NSMutableArray
问题描述
我想用线程扫描照片库,当我的应用程序逻辑正常时,我想将其添加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);
});
}
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
解决方案
如果您有多个线程更新一个属性,您必须同步它们的访问。您可以使用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 队列或某些锁)。
推荐阅读
- python - BeautifulSoup 方法 find() 不适用于其他属性
- c++ - 无法访问 OpenCV 中的 .dll 库
- python - 如何通过别名在 Linux 中将默认的 python3 设置为 python3.9?
- centos - 在 CentOS 8 上无法找到并安装 ImageMagick
- javascript - 如何使用 React 创建自动增长收缩输入?
- task - 为什么我的 leetcode 任务不是从数字 1 开始的?
- javascript - Promise.resolve() 什么时候触发 then() 方法?
- javascript - 为什么 React 源代码是用 JavaScript 而不是 TypeScript 编写的,但仍然有类型?
- swift - 如果默认设置为 true,为什么我需要设置 Analytics.setAnalyticsCollectionEnabled(true)?Firebase + iOS
- sql - 查询以显示类似的项目组,其中包含单个主要项目和多个用逗号分隔的组项目