iOS で本当に奇妙なデリゲートの動作があります。次のように、サブクラス化された UIViewController でカスタム デリゲートを設定しています。
- (void)viewDidLoad
{
[super viewDidLoad];
self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:nil bundle:nil];
self.baseNavigationBar.delegate = self;
self.baseNavigationBar.navigationController = self.navigationController;
[self.navigationController.navigationBar addSubview:self.baseNavigationBar];
}
デフォルトの nib を使用する場合、initWithNibName は nil を使用できます。これは、内部的に nibName の nil をチェックするためです。
if (!nibNameOrNil) {
nibNameOrNil = NSStringFromClass([self class]);
}
baseNavigationBar オブジェクトからのデリゲート宣言は次のようになります。
@property (nonatomic, retain) id<BaseNavigationBarDelegate> delegate;
/*same thing with assign, which I you should use*/
/*and in the .m of course @synthesize*/
そして今、実行中のアプリケーションからの 2 つのスクリーンショット。
最初のものは、 UIViewControllerのサブクラスであるBaseCoreViewControllerのサブクラスであるBaseListViewControllerからのデバッガー値を示しています。
viewDidLoad メソッドが呼び出されると、スクリーンショットが取得されます。
2 つ目は、UIViewサブクラスであるBaseNavigationBarからの値を示しています。
スクリーンショットは、ユーザーが「次へ」ボタンをクリックしたときに一度に撮影されます
- (IBAction)nextAction:(id)sender {
if (self.delegate) {
[self.delegate navigationBarDidClickNextButton:self];
}
}
では、なぜこれが問題なのですか?BaseNavigationBarのボタンをクリックすると、デリゲートは常に nil になるため、プログラムが停止します。しかし、同時にBaseCoreViewControllerからの値を見ると、デリゲートは nil ではありません。非常に奇妙な。
編集
BaseNavigationBar は、UINib loadNibNamed:owner:options: 関数を使用して nib ファイルからロードされます。
編集 2
これでコードはほぼすべてです。
編集 3
最後に、コードの最後の部分でエラーの原因を突き止めました... self = まったく許可されていないものを設定しています...
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (!nibNameOrNil) {
nibNameOrNil = NSStringFromClass([self class]);
}
if (!nibBundleOrNil) {
nibBundleOrNil = [NSBundle mainBundle];
}
NSArray *topLevelObjects = [nibBundleOrNil loadNibNamed:nibNameOrNil owner:self options:nil];
/*Here is the bad part*/
self = [topLevelObjects objectAtIndex:0];
state = BaseNavigationBarButtonStateNext;
if (self) {
self.title = @"";
}
return self;
}
カスタム init を定義する代わりに Class メソッドを使用して解決しました。