iOS奇怪的委托行为?

Posted

技术标签:

【中文标题】iOS奇怪的委托行为?【英文标题】:iOS strange delegate behavior? 【发布时间】:2013-08-30 09:26:56 【问题描述】:

我在 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];

initWithNibName 可以使用 nil,当使用默认 nib 时,因为在内部它会检查 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。

【问题讨论】:

@property(非原子,保留)id 委托;为什么保留? ***.com/questions/918698/… 使用 assign 根本不起作用。我不知道为什么。您对“为什么使用保留”是正确的。我要快速添加模式代码。 self.baseNavigationBar 属性强吗?给更多代码 使用 strong 的行为相同。更多代码来了 【参考方案1】:

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

你已经初始化initWithNibName:nil

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

但它应该像initWithNibName:@"BaseNavigationBar"

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

【讨论】:

我忘了在将 nil 传递给该初始化程序时提及该函数在内部调用 if (!nibNameOrNil) nibNameOrNil = NSStringFromClass([self class]); ,所以 Richt 笔尖被加载。我会快速将其添加到问题中 好的!!对于委托,您不应将属性设置为保留或强,您应该将属性设置为分配.. @injections 你提到的很强大!!不要将属性设置为强,将属性设置为分配。 使用 assign 的行为相同。 @PrashanthRajagopalan 无需在 initWithNibname 上传递您的 nib 名称。仅当您的控制器与多个 nib 关联时才需要 nib 名称。不确定如何投票......?【参考方案2】:

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

【讨论】:

你是完全正确的,我想我刚刚发现了问题。我会快速添加初始化代码,在那里你可以看到问题所在。

以上是关于iOS奇怪的委托行为?的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionViewDelegate 的奇怪行为

UISegmentedControl 和 UIAppearance 的奇怪行为

UITextView 委托行为与自定义 iOS 键盘 (SwiftKey) 不同

AutoLayout 奇怪的行为 iOS

iOS7 中选定 UITableViewCell 的奇怪行为

iOS5 上奇怪的 UIButton 行为