我有一个方法,有时可以在我的代码中调用。下面是一个非常基本的示例,因为代码处理了 iphone 照片库中的图像和文件,并在使用该方法完成时将它们标记为已处理。
@property (nonatomic, assign) dispatch_queue_t serialQueue;
....
-(void)processImages
{
dispatch_async(self.serialQueue, ^{
//block to process images
NSLog(@"In processImages");
....
NSLog(@"Done with processImages");
});
}
我认为每次调用此方法时,我都会得到以下输出......“在 processImages”“使用 processImages 完成”“在 processImages”“使用 processImages 完成”等......
但我总是得到
“在 processImages” “在 processImages” “用 processImages 完成” “用 processImages 完成” 等等......
我认为串行队列会等到第一个块完成,然后开始。对我来说,它似乎正在启动该方法,然后再次调用它并在第一次调用完成之前启动,创建通常不会被处理的图像副本,因为如果它真的连续执行,该方法会知道它们已经被处理了。也许我对串行队列的理解并不具体。有输入吗?谢谢你。
编辑:下面的更多上下文,这就是块中发生的事情......这会导致问题吗?
@property (nonatomic, assign) dispatch_queue_t serialQueue;
....
-(void)processImages
{
dispatch_async(self.serialQueue, ^{
//library is a reference to ALAssetsLibrary object
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
....
//Process the photos here
}];
failureBlock:^(NSError *error) { NSLog(@"Error loading images from library");
}];
});
}
-(id)init
{
self = [super init];
if(self)
{
_serialQueue = dispatch_queue_create("com.image.queue",NULL);
}
return self;
}
这个对象只创建一次,据我所知,永远不能根据我的代码再次创建......我将运行测试以确保。
更新 2:我认为正在发生的事情,如果您同意/不同意,请对此发表评论......
显然,我的主要问题是,这块代码似乎正在同时执行,创建重复条目(两次导入同一张照片),而如果它是串行运行的,通常不会这样做。处理照片时,会对其应用“脏”位,以确保下次调用该方法时会跳过该图像,但这不会发生,并且某些图像会被处理两次。这可能是因为我使用 enumerategroupswithtypes: 在那个 serialQueue 中枚举第二个队列中的对象吗?
- 调用 processImages
- 枚举对象
- 立即从 enumerateObjects 返回,因为它本身是异步的
- 结束对 processImages 的调用
processImages 并没有真正完成,因为 enumerategroups 可能仍在运行,但队列可能已经完成,因为它在 enumerategroups 完成工作之前到达块的末尾。这对我来说似乎是一种可能性?