0

私の質問には、タイトル自体で十分だと思います。ただし、ここでさらに説明します。2 つのビュー コントローラー A と B があるとします。A はベースであり、B をプッシュしています。ある状況では、ビュー (B) で 1 つのボタンがクリックされたときに A が B から親密になるようにします。私がそのインスタンスを持っている場合、Objective Cは直接Aビューを呼び出すことを許可しています。それを行うのは良い習慣ではないと思います。このケースはどのように処理されるべきか..

あなたの提案に感謝します。

4

1 に答える 1

2

「B から親密な A」とは、最初に B のプッシュを担当した A を呼び出したいという意味であり、「戻る」ボタンを使用するか、コードで A に戻るだけです。

[self.navigationController popViewController animated:YES];

B は A へのポインターを必要とせず、Navigation Controller にはそれがあり、B には Nav Controller へのポインターがあります。これは、Nav Controller が BnavigationControllerを作成するときに B のプロパティを設定するためです。

B の何らかのアクションに基づいて A にプロパティを設定する必要がある場合は、デリゲートを使用する必要があります。

B では、 というプロパティを作成しますdelegate

A で、B を作成するときに、デリゲートを A に設定します。

ViewControllerB* vcB = [[ViewControllerB alloc] init];
vcB.delegate = self;
[self.navigationController pushViewController:vcB];

次に、B では、ポップの前にデリゲートを介して A にコールバックできます。

[self.delegate sendMessageWithValue:someValue];
[self.navigationController popViewController animated:YES];

細心の注意を払いたい場合は、メッセージの受け渡しを次のように囲むことができます。

if ([self.delegate respondsToSelector:@selector(sendMessageWithValue:)]) { ... }

B がデリゲートであることを除いて、A について何も知らずにこれを機能させるには、B はヘッダーでデリゲート プロトコルを宣言する必要があります (上記の@interface) 。

@protocol BDelegateProtocol
- (void) sendMessageWithValue:(int)someValue;
@end

delegateB's でプロパティを宣言するときは@interface、従うことになるプロトコルを指定します。

@property (nonatomic, weak) id <BDelegateProtocol> delegate;

そして、A の @interface ヘッダーで、そのプロトコルに従っていることを宣伝します。

#import BViewController;

@interface AViewController:UIViewController <BDelegateProtocol>

これがあなたが求めている疎結合です。B は A のヘッダーをインポートする必要はありません。B のプロトコル仕様に準拠していること以外は、A について何も知る必要はありません。

B は A へのポインターを保持しますが、弱いポインターです。これはとても重要です。デリゲート プロパティがstrongの場合、B はそのデリゲートの保持カウントを 1 増やします。デリゲートが B へのストロング ポインター保持している場合、どちらも割り当てを解除できません。A が存在する間、B の保持カウントは常に少なくとも 1 になります。同様に、B が存在する間、A の保持カウントは常に 1 になります。どちらも破壊できません。

この特定のケースでは、A は Nav コントローラーのように B を保持する必要はありませんが、デリゲートがデリゲーターを作成して所有するオブジェクトであることが非常に多いため、頻繁に発生する可能性がある状況です。Apple の実用的なメモリ管理の「保持サイクルを回避するために弱い参照を使用する」を参照してください。

于 2013-01-17T09:35:47.513 に答える