0

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 メソッドを使用して解決しました。

4

2 に答える 2