Objective C:在 init 方法中使用 self 作为文件所有者是不好的做法吗?

Objective C : is bad practice using self as file's owner in init method?

我是 ObjC 的菜鸟,我试图理解一些基本概念,这些概念似乎也在网络上成千上万的教程中被混淆了。我的问题是文件所有者的管理。例如,如果我想要 UITableView 对象中的自定义单元格,我需要:

1) to make, in Interface Builder, a NIB file with my custom cell
2) create my `CustomCellControllerClass` and set is as Custom Class
   in the Identity Inspector;
3) in my `CustomCellControllerClass` add the IBOutlet property
4) connect every item in my NIB file with respective Outlet 

所以,我的连接检查器中有这样的东西

 item --- File's Owner

现在,开始问题:在提出的所有方法中,对我来说最多的 "clean" 似乎是在 CustomCellControllerClassinit 方法中初始化我的自定义单元格 ;像这样:

-(id) init
 {
   self=[super init];
   self=[[[NSBundle mainBundle]
        loadNibName:@"CustomCellNib" 
        owner: self options:nil] lastObject];
   return self;
 }

现在,当我启动程序时似乎一切正常,但是...我无法控制奥特莱斯! 我认为因为我将 self 对象的旧实例设置为所有者,所以 loadNibName:Owner:options: return 是一个新对象,所有者是旧的 self 对象。因此,Outlets 之间的绑定是使用旧的 self 对象进行的。 我希望我加载的 Nib 有自己的所有者(loadNibName:Owner:options: return CustomCellControllerClass 对象,所以将它设置为自己的所有者并不奇怪),但似乎不可能..在我看来这一切都非常递归! 我发现部分 "resolve" 问题的方法如下:

-(id) init
 {
   self=[super init];
   CustomCellControllerClass* ccp=[[[NSBundle mainBundle] 
                                  loadNibName:@"CustomCellNib" 
                                  owner: self options:nil] lastObject];
   [self addSubView:ccp];
   return self;
 }

所以,我没有丢失我原来的 self 参考资料,我可以处理我的 属性。 问题是现在我的 CustomCell 只是一个子视图,考虑到所有的问题,我想让它成为 "main" 视图。 我的推理对吗?我哪里错了?如何更好地解决这些问题?

使用 table 视图注册 NIB 是处理此问题的正确方法。


直接回答你的问题,将self重新赋给-loadNibName:owner:options:的第一个结果,一共是kludge!但是……有时需要拼凑。

作为旁注,不要将 self 作为所有者传递,传递 nil,并对 NIB 名称使用 class 方法,它将使 subclass更容易。

- (instancetype)init
{
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *name = [[self class] nibName];
    self = [bundle loadNibName:name owner:nil options:nil].firstObject;
    return self;
}

+ (NSString *)nibName
{
    return @"CustomCellNib";
}

这是关于使用 self 作为所有者的更新。在代码示例中,您将 self 作为所有者传递,然后将 self 重新分配给新对象。

-(id) init
 {
   /* old self */self=[super init];
   /* NIB object */self=[[[NSBundle mainBundle]
        loadNibName:@"CustomCellNib" 
        owner: /* old self */self options:nil] lastObject];
   return /* NIB object */self;
 }

可以看到,owner是旧的self,但是返回值是nib对象。在 NIB 中分配给所有者的任何内容都将分配给旧的自己并丢失。


解决方案是当你有这种设置时永远不要使用 NIB 中的所有者,你需要设置的任何插座都必须建立到 NIB 对象。