块回调——当原始对象被释放时

block callbacks -- when original object is deallocated

我正在调用我的 DatabaseManager 来保存在 viewController 中创建的对象,如下所示:

  [DatabaseManager addUniqueObject:fooChild key:[fooParent fooChildKey] toObject:self.foo callback:^(BOOL succeeded, NSError *error) {


            if (error) {
                [[UIApplication sharedApplication] endBackgroundTask:self.sendBackgroundTaskId];
                return;
            }


               [self.tableView reloadData];
               [self scrollToBottomAnimated:YES];
            }

            [[UIApplication sharedApplication] endBackgroundTask:self.sendBackgroundTaskId];
        }];

addUniqueObject 是我的 DatabaseManager 中的一个 class 方法(如您所见,我使用 Parse 作为后端):

 + (void)addUniqueObject:(PFObject*)uniqueObject key:(NSString*)key toObject:(PFObject*)object callback:(void(^)(BOOL succeeded, NSError *error))callback {

    if (uniqueObject) {
        [PFCloud callFunctionInBackground:@"addUniqueObjectToObject"
                           withParameters:@{@"classKey":[object parseClassName],
                                            @"objectId":[object objectId],
                                            @"keyToAdd":key,
                                            @"objectToAddClassKey":[uniqueObject parseClassName],
                                            @"objectToAddId":[uniqueObject objectId],

                                            }
                                    block:^(NSMutableDictionary *results , NSError *error) {
                                        if (!error) {
                                            callback(YES, error);
                                        }
                                        else {
                                            callback(NO, error);
                                        }
                                    }];
    }

}
  1. 第一个问题 - 因此,如果我创建了这个对象,然后导航离开并因此在保存执行之前弹出这个 VC,那么 self.tableView 或任何其他 属性 此时我在完成块中引用的是 nil,对吗?

  2. 第二个问题 - 我将完成块传递给 DatabaseManager - 如果原始 VC 被销毁,这个完成对象是否仍然存在?在执行 callback() 之前是否必须检查此块是否存在?

这对我来说似乎没有任何问题,所以直到现在我才质疑它。但我想明白。

  1. 不,您的 VC 不会被释放,因为 self 是在块内捕获的。如果你想让它被释放,你应该这样写:

    __weak typeof(self) weakSelf = self; // we don't increase retain count here
    [DatabaseManager addUniqueObject:fooChild key:[fooParent fooChildKey] toObject:self.foo callback:^(BOOL succeeded, NSError *error) {
        __strong typeof(self) self = weakSelf;
       // if weakSelf is still not deallocated, it will be retained until block finishes
    

    考虑使用 @strongify/@weakify 代替此代码段。

  2. 是的。 callback 由您传递给 callFunctionInBackground:withParameters:block: 的块保留,因此在执行块之前不会释放它。如果你确定没有人会用 callback:nil 调用你的函数,那么你不需要检查它是否仍然存在于完成块中。