iphone - iOS 奇怪的委托(delegate)行为?

标签 iphone ios objective-c uiviewcontroller delegates

我在 iOS 中有一个非常奇怪的委托(delegate)行为。我在子类化的 UIViewController 中设置自定义委托(delegate),如下所示:

- (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 对象的委托(delegate)声明如下所示:

@property (nonatomic, retain) id<BaseNavigationBarDelegate> delegate;
/*same thing with assign, which I you should use*/
/*and in the .m of course @synthesize*/

现在有 2 个正在运行的应用程序的屏幕截图。

第一个显示来自 BaseListViewController 的调试器值,它是 BaseCoreViewController 的子类,BaseCoreViewControllerUIViewController 的子类。

屏幕截图是在调用 viewDidLoad 方法时截取的。

List Controller

第二个显示来自 BaseNavigationBar 的值,它是一个 UIView 子类。

截图是在用户点击“下一步”按钮的时候截取的

- (IBAction)nextAction:(id)sender {
    if (self.delegate) {
        [self.delegate navigationBarDidClickNextButton:self];
    }
}

NavigationBar

那么为什么这是个问题呢?通过单击 BaseNavigationBar 中的按钮,我的委托(delegate)始终为 nil,因此程序卡住了。但是当同时查看来自 BaseCoreViewController 的值时,委托(delegate)不是 nil。很奇怪。

编辑

BaseNavigationBar 是使用 UINib loadNibNamed:owner:options: 函数从 nib 文件加载的。

编辑2

这就是几乎所有的代码。

编辑3

最后我们在最后一段代码中找到了错误的来源...设置 self = something totally not allowed...

- (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 的问题。

最佳答案

如果您使用的是 nib 文件,则应在初始化类对象时声明 nib 类。

你已经初始化了initWithNibName:nil

self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:nil bundle:nil];

但它应该像initWithNibName:@"BaseNavigationBar"

self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:@"BaseNavigationBar" bundle:nil]; 

关于iphone - iOS 奇怪的委托(delegate)行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18529446/

相关文章:

objective-c - UISearchBar 消失在 UINavigationBar 后面

iphone - NSIncation 将 C 数组传递给 Objective-C 方法

objective-c - 如何从 NSString 获取每一行?

ios - CoreData故障-如何获取数据

iphone - 默认启动画面无法获取区域格式

iphone - 在iOS应用程序中显示 "Tip of the day"(不使用服务器)

iphone - 如何在 UITextView 中制作可点击的链接

iphone - GKTurnBasedParticipant 信息

ios - 启动屏幕在 iPad 设备中不起作用

ios - UINavigationBar 外观 setBackgroundImage 隐藏状态栏