【问题标题】:Overriding init method to allocate memory for instance variable object重写 init 方法为实例变量对象分配内存
【发布时间】:2013-02-11 20:12:07
【问题描述】:

我正在尝试覆盖类的init 方法,以便初始化对象也初始化ivar 对象:

-(id)init 
  {
    if (self = [super init])
    {
       someIVarObject = [SomeClass alloc] init];
    }
    return self;
  }

1) 这段代码还能工作吗?即便如此,是否不鼓励这种解决方案?
2) 为什么 if 条件不是 == ?是任务吗?如果是这样,为什么if

对不起,如果这很明显! >_

【问题讨论】:

标签: objective-c initialization overriding alloc ivar


【解决方案1】:

是的,它会起作用,而且它仍然是它应该做的方式。

它的作用是调用[super init] 并允许它做三件事之一;

  • 返回自我(即相同的对象self 已设置为。
  • 返回一个全新的对象。
  • 返回 nil 表示失败。

然后将结果分配给self,以确保构造函数的其余部分在正确的对象上运行,以防它发生变化。 if 用于捕获 [super init] 返回 nil 的情况,在这种情况下应跳过构造函数的其余部分。

【讨论】:

  • "afaik 这仍然是它应该做的方式" 如果你真的想要一个 ivar。 @propertys 通常是更好的解决方案。
【解决方案2】:

1) 这里你声明了一个局部变量someIVarObject。您应该在大括号中的类的接口或实现中声明它,然后将其分配为someIvarObject = ...。一个例子:

@implementation MyClass {
    SomeClass *someIvarObject;
}

- (id)init
{
    if(self = [super init])
    {
        someIvarObject = [[SomeClass alloc] init];
    }
    return self;
}

@end

2) 这是一项任务。这个习语背后有很长的历史,但它主要归结为处理[super init] 返回与最初调用init 不同的对象的可能性。

【讨论】:

    【解决方案3】:

    这...

    if(self = [super init])
    

    会起作用,但它会给你一个编译器警告(除非你关闭了这个警告)。

    您也可以使用双括号来隐藏警告:

    if((self = [super init]))
    

    我目前的偏好:

    self = [super init];
    if(self)
    

    【讨论】:

    • 你当前的偏好很干净,就像@AndreyChernukha 的建议
    【解决方案4】:

    你有一些拼写错误,不平衡的括号,你说的是 ivar 不是 ivar(你在 if 中声明它,这使得它的范围是该块的本地。你想放置实例变量在 @implementation@interface 声明之后的 {}s 中)。但是,是的,这通常是这样工作的。

    但是,我会认真考虑您是否真的需要 ivar。我不记得上次在我的代码中使用它是什么时候了。在我曾经使用它们的 99% 的情况下,@property 现在是一个更好的解决方案。

    另外一个好处是,@propertys 可以合成自己的 getter 和 setter,(通常)无需编写手动的 allocing 样板文件,因此这个问题没有实际意义。

    【讨论】:

    • 对不起,我意识到这是一个旧评论,但如果你看到这个,你能解释一下当你不使用属性时你需要什么手动分配样板。你是指设置、获取等还是其他重新分配的东西?
    • 太长了,我不记得我在说什么了 ;-) 但我认为你不需要任何额外的分配样板。您需要特别注意保留/释放语义。 ivar 只是一个指针。属性是具有已知所有权语义(强、弱、复制等)的引用,它让 ARC(或 MRC 中的合成 getter/setter)为您管理引用计数。
    • 酷 - 我猜你的意思是当你不使用属性时手动编写设置和获取代码。感谢您回到主题。
    【解决方案5】:

    1) 这段代码可以工作,但是这一行:

    SomeClass *someIVarObject = [SomeClass alloc] init];
    

    有点意思。在 .h 文件中声明 SomeClass *someIVarObject 并在 init 中像这样初始化它:

    someIVarObject = [SomeClass alloc] init];
    

    2) 这行if (self = [super init]) 相当于:

    self = [super init]; if (self != nil)
    

    即它确保基类的 init 方法返回了正确的值

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-23
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      相关资源
      最近更新 更多