我想从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被解除时,它在完成时调用VC1方法 - 所有这些都不需要定义协议或使用委托(我发现对某些人来说非常麻烦)在这种情况下扩展 - 但非常可靠)可以推荐吗?
非常感谢!
答案 0 :(得分:5)
这是可能的,但您必须注意保留周期。请记住,块将捕获其中引用的任何变量,包括self。如果VC1保持对VC2的强引用,那么请注意不要让该块也强烈引用VC1。如果需要,在块外面对自己进行__weak
引用并使用它。
最简单的方法是创建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];
}