「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
delegate
B'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 の実用的なメモリ管理の「保持サイクルを回避するために弱い参照を使用する」を参照してください。