如何在iOS中为后台线程创建带条件定时器的GCD块?

时间:2014-06-06 06:05:37

标签: ios objective-c grand-central-dispatch nstimer background-thread

以下是我在plist文件中读取后台线程上传视频的方法。

现在我需要的是,一旦他们从plist读取所有条目并完成第一个块的执行,我想检查完成块,即plist文件中有任何新条目...如果不是只调用{{1}几次之后。任何人都可以建议我怎么做?现在我只是在完成块中调用相同的方法,所以它继续运行...

startThreadForUpload

1 个答案:

答案 0 :(得分:1)

为什么不将plist再次读入一个新的可变字典,然后删除已处理的键的对象并重复该过程。

您应该将实际的上传功能重构为新方法,以便您可以递归调用,直到所有视频都上传完毕。然后,您可以在延迟之后再次执行原始选择器,或使用dispatch_after。

将for循环重构为一个名为uploadVideos:的新方法,并将其调用为:

- (void)startThreadForUpload
{
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    assetManager = [AssetManager sharedInstance];
    NSDictionary *videoListDict = [assetManager allVideoFromPlist];

    // call the new method defined below to upload all videos from plist
    [self uploadVideos:videoListDict.allValues];

    // create a mutable dictionary and remove the videos that have already been uploaded
    NSMutableDictionary *newVideoListDict = [assetManager getAllVideoFromPlist].mutableCopy;
    [newVideoListDict removeObjectsForKeys:videoListDict.allKeys];

    if (newVideoListDict.count > 0) {
      // new videos, so upload them immediately
      [self uploadVideos:newVideoListDict.allValues];
    }

    // start another upload after 300 seconds (5 minutes)
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(300 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      [self startThreadForUpload];
    });
  });
}

- (void)uploadVideos:(NSArray *)videos
{
  AmazonManager *amazonManger = [AmazonManager sharedInstance];

  for (NSData *videoData in videos) {
    Video *vidObject = (Video *)[NSKeyedUnarchiver unarchiveObjectWithData:videoData];

    // call a method defined in a category, described below
    [amazonManager uploadVideo:vidObject];
  }
}

您应该在AmazonManager上定义一个类别,以保持良好的关注点分离:

// put this in AmazonManager+VideoUpload.h
@interface AmazonManager (VideoUpload)
- (void)uploadVideo:(Video *)video;
@end

// put this in AmazonManager+VideoUpload.m
@implementation AmazonManager (VideoUpload)

- (void)uploadVideo:(Video *)video
{
  [self uploadVideoWithVideoName:video.videoName IsImage:NO VideoObject:video];
  [self uploadVideoWithVideoName:video.thumbImageName IsImage:YES VideoObject:video];
}

@end

现在的问题是,每次调用方法startThreadForUpload时,它都会上传plist文件中的所有视频。如果您总是打算阅读需要上传的视频,则应保存已上传的视频,以避免上传两次。

希望有所帮助:)

相关问题