方法参数在使用之前被释放

时间:2016-06-29 15:31:27

标签: ios multithreading object thread-safety block

我在类方法中有下一个问题,当实现一些长时间运行的过程时,那就是传递的参数似乎被解除分配。

我从课外调用该方法。

+ (void)downloadVideoForExercise:(Exercise *)exercise{

    dispatch_queue_t serialQueue = dispatch_queue_create("com.blah.queue", DISPATCH_QUEUE_SERIAL);

    dispatch_async(serialQueue, ^{

        [self isMaximumDownloadCapacityReached:^(BOOL success) {
            if (success) {
                return;
            }
        }];

        [self shouldDownloadVideoForExercise:exercise
                          andCompletionBlock:^(BOOL success) {
                              if (success == NO) {
                                  return;
                              }
                          }];

        [NetworkManager downloadFileFromURL:exercise.videoServerURL
                             andSaveLocally:YES
                              andCompletion:^(BOOL success) {

                                  dispatch_async(dispatch_get_main_queue(), ^{
                                      RLMRealm *realm = [RLMRealm defaultRealm];
                                      if (![realm inWriteTransaction]) {
                                          [realm beginWriteTransaction];
                                      }
                                      if (success) {
                                          //save the new local link
                                          NSString *videopath = [NetworkManager getVideoLocalURLFromServerURLForExercise:exercise.videoServerURL];
                                          exercise.videoLocalURL = videopath;
                                          //change flag for ExerciseVideoDownloadState
                                          exercise.videoDownloadState = isDownloadCompleted;
                                      }else{
                                          //change flag for ExerciseVideoDownloadState
                                          exercise.videoDownloadState = isNotDownloaded;
                                      }
                                      if ([realm inWriteTransaction]) {
                                          [realm commitWriteTransaction];
                                      }
                                  });

                              }];

    });

}

我已经考虑过将参数与__strong或__block一起使用 但没有成功。 提前感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

问题是由我正在使用的库Realm生成的。 问题是对象的所有更改都是一些C ++类后面的句柄,这些C ++类执行一些自定义内存句柄,因此当我调用该对象时,它返回的不是nil值,而是指向正在执行的C ++对象的指针工作。通过这样做来解决这个问题:

- (void)downloadVideoForExercise:(Exercise *)exercise{
    if (!serialQueue) {
        serialQueue = dispatch_queue_create("com.blah.queue", DISPATCH_QUEUE_SERIAL);
    }

    NSString *url = exercise.videoServerURL;

    dispatch_async(serialQueue, ^{

        [self isMaximumDownloadCapacityReached:^(BOOL success) {
            if (success) {
                return;
            }
        }];

        [self shouldDownloadVideoForExercise:exercise
                          andCompletionBlock:^(BOOL success) {
                              if (success == NO) {
                                  return;
                              }
                          }];

        [self downloadFileFromURL:url
                             andSaveLocally:YES
                              andCompletion:^(BOOL success, NSString *localURL) {

                                  dispatch_async(dispatch_get_main_queue(), ^{
                                      RLMRealm *realm = [RLMRealm defaultRealm];
                                      if (![realm inWriteTransaction]) {
                                          [realm beginWriteTransaction];
                                      }
                                      if (success) {
                                          //save the new local link
                                          NSString *videopath = [self getVideoLocalURLFromServerURLForExercise:exercise.videoServerURL];
                                          exercise.videoLocalURL = videopath;
                                          //change flag for ExerciseVideoDownloadState
                                          exercise.videoDownloadState = isDownloadCompleted;
                                      }else{
                                          //change flag for ExerciseVideoDownloadState
                                          exercise.videoDownloadState = isNotDownloaded;
                                      }
                                      if ([realm inWriteTransaction]) {
                                          [realm commitWriteTransaction];
                                      }
                                  });

                              }];

    });

}