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 个屏幕截图。

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

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

列表控制器

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

当用户单击“下一步”按钮时,一次截取屏幕截图

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

导航栏

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

编辑

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;
}

使用 Class 方法而不是定义自定义 init 来解决。

4

2 回答 2

2

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

你已经初始化initWithNibName:nil

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

但它应该像initWithNibName:@"BaseNavigationBar"

self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:@"BaseNavigationBar" bundle:nil]; 
于 2013-08-30T09:38:01.403 回答
1

不确定是什么问题。需要更多代码来分析问题。但是我可以看到两个屏幕截图中 BaseNavigationBar 的地址是不同的。这意味着控制器中存在的 BaseNavigationBar 对象不是第二个屏幕截图中获得 nextAction 事件的对象。

于 2013-08-30T10:04:25.397 回答