iphone - 使用完成 block 呈现和关闭 UIViewController - 没有协议(protocol)和委托(delegate)

标签 iphone ios uiviewcontroller

我想从 VC1 的实例中呈现一个 VC2 的实例,并向它传递一个要在 VC2 时执行的完成 block 解雇自己。传递的完成 block 将是对 VC1 实例的方法调用。

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

从 VC1 呈现 VC2 通常是:

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

在 VC2 中

    [self dismissViewControllerAnimated:YES completion: nil];

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

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

...但我想 VC2 也可以 self 解散 - 但是我不确定这是否总是可以的。

虽然在 Apple 文档中,他们仍然推荐委托(delegate)方案 - 但 self 解雇也有效。

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

我想在 VC2 中做这样的事情:

    [self dismissViewControllerAnimated:YES completion: passedBlockFromVC1];

当呈现 VC2 时,将此 passedBlockFromVC1 以某种方式传递给 VC2 - 同时包含 VC1 方法。

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

总而言之,我正在寻找一种解决方案来从 VC1 呈现 VC2,当 VC2 被取消时,它会在完成时调用 VC1 方法——所有这些都不需要定义协议(protocol)或使用委托(delegate)(我发现这对某些人来说非常麻烦在这种情况下扩展 - 但非常可靠)

这是否可能并被推荐?

非常感谢!

最佳答案

这是可能的,但您必须注意保留循环。请记住, block 将捕获其中引用的任何变量,包括 self。如果 VC1 保持对 VC2 的强引用,那么请注意不要让该 block 也对 VC1 具有强引用。如果需要,在 block 外创建一个对 self 的 __weak 引用并使用它。

See the Apple Documentation for more information about retain cycles using blocks and how to avoid them.

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

您可以像这样声明一个属性来将 block 存储为实例变量:

@property (nonatomic, copy) dispatch_block_t completionBlock;

使用标准的 libdispatch block 类型。

然后定义一些方法来设置它:

-(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 方法以调用完成 block (如果有)。

-(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];
}

关于iphone - 使用完成 block 呈现和关闭 UIViewController - 没有协议(protocol)和委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12658147/

相关文章:

ios - 我有一个包含不同/多个 UIView 的 Storyboard ,我希望每个 UIView 都有一个 ViewController。 swift

iOS - 为动态创建的 View 设置适当的约束

ios - IOS7中的UIButton背景图片

ios - 为什么 Unity iOS 应用程序如此庞大?

ios - 在解析中删除指向 PFObject 的指针?

iphone - iPhone 编程中属性的使用

iphone - 我怎么能不重复地随机播放视频

ios - AVAudioPlayer 不播放长音?

iphone - 如何在 iOS 应用程序中向图标添加通知

ios - 卸载/重新加载 View Controller 的正确方法