3

我想VC2从一个实例中展示一个实例,VC1并将它传递给一个完成块,以便在VC2它自行关闭时执行。传递的完成块将是对VC1实例的方法调用。

这样做的正确方法是什么?

虽然从 VC1 呈现 VC2 通常是:

    VC2 *vc2 = [[VC2 alloc] init];
    [self presentViewController:vc2 animated:YES completion: nil];

在 VC2 中

    [self dismissViewControllerAnimated:YES completion: nil];

(ps 通常我会在 VC2 中像这样关闭 VC2 - 即调用协议中声明的 VC1 方法

  [self.delegate dismissVC2]; // basically meaning VC1 to dismiss VC2

...但我猜 VC2 也可以自行解散 - 但是我不确定这总是可以的。

在 Apple 文档中,他们仍然推荐委托方案 - 但是自我解雇也有效。

您也可以对此发表评论吗?)

我想在 VC2 中这样做:

    [self dismissViewControllerAnimated:YES completion: passedBlockFromVC1];

并且在呈现 VC2 时passedBlockFromVC1以某种方式将其传递给 VC2 - 同时包含 VC1 方法。

这样做的正确方法是什么?

总之,我正在寻找一种从 VC1 呈现 VC2 的解决方案,当 VC2 get 被解除时,它会在完成时调用 VC1 方法——所有这些都不需要定义协议或使用委托(我觉得这在某种程度上很麻烦)案例 - 但非常可靠)

这是可能的和推荐的吗?

非常感谢!

4

1 回答 1

5

这是可能的,但您必须注意保留周期。请记住,块将捕获其中引用的任何变量,包括 self. 如果 VC1 保持对 VC2 的强引用,请注意不要让块也对 VC1 有强引用。如果需要__weak,请在块外引用 self 并使用它。

有关使用块的保留循环以及如何避免它们的更多信息,请参阅 Apple 文档。

最简单的做法是继承 UIViewController 并创建自己的方法和属性来实现这一点。

您可以声明一个属性以将块存储为实例变量,如下所示:

@property (nonatomic, copy) dispatch_block_t completionBlock;

使用标准的 libdispatch 块类型。

然后定义一些设置方法:

-(void)presentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void (^)(void))completion dismissCompletion:(dispatch_block_t)dismissCompletion{
    self.completionBlock = dismissCompletion;
    [super presentViewController:viewController animated:animated completion:completion];
}

然后重写dismiss方法以调用完成块(如果有)。

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion{
    if (self.completionBlock && ! completion){
        [super dismissViewControllerAnimated:flag completion:self.completionBlock];
        self.completionBlock = nil;
        return;
    }
    [super dismissViewControllerAnimated:flag completion:completion];
}
于 2012-09-30T16:25:35.530 回答