2

我对 iOS 开发很陌生,我正面临一个多线程问题。

我正在使用带有 SDWebImage 的KTPhotobrowser创建照片和视频库。我必须在每张图片上加载一些外部数据,我不想影响画廊滚动视图的流畅度。

所以,我正在尝试使用NSOperationand来做到这一点NSOperationQueue,但我不确定我做得对。

如果用户没有停留在图片上并继续滚动,我想要的是停止加载过程。

我当前的代码:

//setCurrentIndex is called when the scrollView is scrolled

- (void)setCurrentIndex:(NSInteger)newIndex {

   [loadingQueue_cancelAllOperations]; 
   currentIndex_ = newIndex;
   [self loadPhoto:currentIndex_];     
   NSInvocationOperation *InvocationOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadInfosAtIndex:) object:newIndex];

   [loadingQueue_ addOperation:InvocationOp];      
   [InvocationOp release];

   [selfloadPhoto:currentIndex_ + 1];
   [selfloadPhoto:currentIndex_ - 1];
   [selfunloadPhoto:currentIndex_ + 2];
   [selfunloadPhoto:currentIndex_ - 2]; 
}

-(void) loadInfosAtIndex:(NSInteger)index {

   if (index < 0 || index >= photoCount_) {
        return;
   }

   KTPhotoView* photoView = [photoViews_ objectAtIndex:index];
   if([photoView infosAlreadyLoaded]){
       NSLog(@"%d Already Loaded", index);
       return;
   }

    //Get the extra information by calling a web service
    photoView.infosAlreadyLoaded = YES;
}

我认为这不是正确的方法......有没有人有任何建议?

4

2 回答 2

3

与其依赖基于调度的取消(这会使您处于不确定状态),不如拥有一个具有原子访问权限的取消实例变量(通过原子属性或带有互斥锁的 BOOL ivar)。

然后,您只需将取消标志设置为 YES 并定期在 loadInfosAtIndex 中检查它,而不是 [loadingQueue_cancelAllOperations]。这本质上是轮询取消,如果涉及代码,可能会很痛苦。但它的优点是让您能够通过读取标志来优雅地处理取消。作为处理的一部分,您可以将 isRunning 标志(也需要是原子/互斥的)设置为 NO 并通过返回退出线程。

在主线程中,将取消标志设置为YES后,可以等到isRunning标志为NO后再开启一个新线程。

于 2013-02-05T11:16:15.493 回答
-1

[loadingQueue_cancelAllOperations],根本不会立即取消操作,它只会取消队列中尚未开始执行的操作。

如果队列中的操作已经开始,则只有在操作完成后才将其删除。有关 cancelAllOperations 的更多信息

我认为您可能希望使用 GCD async 来删除当前正在执行的块。

于 2013-02-05T09:21:43.417 回答