2013-03-19 171 views
1

我一直在为我的对象创建自定义初始化程序,仅仅因为它感觉比以其他方式设置变量更好。在这些初始化程序中,我通常会设置对象的变量,然后将调用返回到主init。自定义对象初始化程序

因此,例如,在UIViewController子类我的代码看起来是这样的:

-(id)initWithValue:(int)val { 
    self.value = val; 
    return [self initWithNibName:nil bundle:nil]; 
} 

其中value是属于该视图控制器子类的整数,并且有比平常更多的价值。

但是,最近我开始设置自己的第一个,因为我认为self = [self init...]将取代当前类的实例,因此我会失去自己的实例。 所以,我开始做:

-(id)initWithValue:(int)val { 
    self = [self initWithNibName:nil bundle:nil]; 
    self.value = val; 
    return self; 
} 

然后我最近检查的原始版本,并意识到,一切都没有正常工作,该变化是不必要的。

所以,我的问题是这样的:

  1. 什么是[超级initWithNibName:束:]做的,这是造成它创建一个对象,但不会取代原来的对象?
  2. 是两个版本之一比另一个更好使用还是它们都是等价的?如果一个更好,应该使用哪个?

谢谢先进!

回答

0

您写的第一个代码不会存储value,因为在创建对象之前,您正试图存储数据。 但是,第二个代码,需要更好的做法,即,像这样的小改...

-(id)initWithValue:(int)val { 
    self = [self initWithNibName:nil bundle:nil]; 

    if(self) 
    _value = val; 

    return self; 
} 

希望这是对你有用... :-)

+0

这就是我想,但我尝试设置值,然后做'自我=可能返回的零值自initWithNibName:束:]'然后打印出的价值观和他们是正确的。我假设自己不会总是被改变,但是按照自己的方式做事通常更安全。 – Jsdodgers 2013-03-19 06:29:33

+0

另外,感谢关​​于'_value'的提示。只是为了确保我清楚这一点,使用'_value'时,'[self setValue:]'不会被调用,对吗?如果是这样,是不使用self.value的唯一原因还是另一个? – Jsdodgers 2013-03-19 06:31:34

+0

价值属性在你的情况下,所以当综合使用像这样的标准代码... @synthesize value = _value; 您也可以使用[self setValue:]来获取值。 – 2013-03-19 06:35:05

1

请使用下面的代码覆盖init方法

-(id)initWithValue:(int)val 
{ 
    self = [super init]; 
    if(self) 
    { 
    self.value = val; 
    } 

    return self; 
} 
0

[super initWithNibName:bundle:]实际上调用了超类的方法。 如果你使用[self initWithNibName:bundle:]实际上它会调用initWithNibName:bundle的重写:当然你必须重写它,否则它也会调用超类方法。所以如果你想在initWithNibName的重写中做一些初始化,那么你可以使用[self initWithNibName:bundle:],但如果你不需要做额外的初始化,那么to方法之间没有区别;

2

你应该这样做以下方式:

- (id)initWithValue:(int)val { 
    self = [super initWithNibName:nil bundle:nil]; 
    if (self) { 
     _value = val; 
    } 
    return self; 
} 

在iOS系统中,一个常见的模式是返回零,如果发送到初始化方法的参数是无效的。该值将是以下两件事之一:当前指向self或nil的指针。如果超级调用返回nil,那么该对象没有正确设置,所以你应该返回nil。做self = [super initWithNibName:nil bundle:nil];只是可以更容易地尊重超级

+0

注意,它实际上是完全有效的返回不同的对象(而不是'nil'或'self'的电流值)从'init'方法。这样做是为了用一个新的 - 也许是一个从一个笔尖加载的,或一个特定的子类,或一个单身人士替换现有的对象。您应该立即将这个对象存储到'self'中,并在init'方法的其余部分使用它来代替原来的实例。 – 2013-03-19 07:07:26

+0

这些通常被称为类集群,并且不应因此而继承它们。自我可能会最终成为的超级类,以便访问方法和实例变量不同子类型在当前类定义会导致EXC_BAD_ACCESS – 2013-03-19 07:22:18

+0

尼克,类簇只有一个超类可能会返回一个不同的实例的*很多*的原因之一来自'-init'。请参阅Mike Ash的文章[可可初始化程序的原理和方法](http://www.mikeash.com/pyblog/the-how-and-why-of-cocoa-initializers.html),特别是神话/事实部分, 更多细节。 – 2013-03-20 03:20:49