用完成块来呈现和解除UIViewController – 没有协议和委托

我想从VC1一个实例中展示一个VC2实例,并在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也可以自行解散 – 但是我不确定这是否总是好的。

在苹果文档中,他们仍然推荐授权scheme – 但是自我解雇也是如此。

你能评论一下吗?)

我想在VC2中这样做:

  [self dismissViewControllerAnimated:YES completion: passedBlockFromVC1]; 

当提交VC2时,通过这个passedBlockFromVC1以某种方式传递给VC2 – 同时包含一个VC1方法。

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

总之,我正在寻找一个解决scheme来展示来自VC1的VC2,当VC2被解散时,它在完成时调用一个VC1方法 – 所有这些都不需要定义一个协议或者使用一个委托(在这里我觉得很麻烦)案件 – 但非常可靠)

这是可能的,并build议?

非常感谢!

这是可能的,但你必须留意保留周期。 请记住,一个块会捕获其中引用的任何variables,包括self。 如果VC1保持对VC2的强引用,那么注意不要让该引用对VC1有很强的参考。 如果需要的话,在块之外对自己做一个__weak引用并使用它。

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

最简单的做法是inheritanceUIViewController,并使你自己的方法和属性来实现这一点。

你可以声明一个属性来存储一个块作为一个实例variables,如下所示:

 @property (nonatomic, copy) dispatch_block_t completionBlock; 

使用标准的libdispatch块types。

然后定义一些设置方法:

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