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でこのようなsthをしたいと思います:

    [self dismissViewControllerAnimated:YES completion: passedBlockFromVC1];

そして、VC2を提示するときpassedBlockFromVC1は、VC1メソッドを含みながら、これを何らかの方法でVC2に渡します。

これを行う正しい方法は何でしょうか?

要約すると、VC1からVC2を提示するソリューションを探しています。VC2が却下されると、完了時にVC1メソッドが呼び出されます。プロトコルを定義したり、デリゲートを使用したりする必要はありません(これは、ある程度面倒です。ケース-しかし非常に信頼できる)

それは可能であり、推奨されていますか?

どうもありがとう!

4

1 に答える 1

5

これは可能ですが、保持サイクルに注意する必要があります。ブロックは、self を含め、ブロック内で参照されるすべての変数をキャプチャすることに注意してください。VC1 が VC2 への強い参照を保持している場合は、ブロックが VC1 への強い参照も持たないように注意してください。必要に応じて__weak、ブロック外の自己への参照を作成し、それを使用します。

ブロックを使用したリテイン サイクルとその回避方法の詳細については、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 に答える