自我= [超级初始化]再访
我偶然发现了这个帖子In Objective-C why should I check if self = [super init] is not nil?自我= [超级初始化]再访
我能理解this syntax:
- (id)initWithString:(NSString *)aString
{
self = [super init];
if (self)
{
instanceString = [aString retain];
}
return self;
}
- (id)init;
{
if (!(self = [super init]))
return nil;
// other stuff
return self;
}
,但我还是不明白“标准”模板语法
- init {
if((self = [super init])) {
// set up instance variables and whatever else here
}
return self;
}
有人可以尽可能清楚地告诉(3)与(1)或(2)相比,或多或少有什么作用?我读过的所有内容都很混乱(为什么人们不能同意纯粹技术的东西看起来像政治:))
不过,当我阅读作者的文章,并且我可以模糊地理解它,远远超出了仅仅是语法糖辩论或品味的问题。例如it is said:
奇怪然后,当壳体3是压倒性多见,支持1,2和4,但不兼容与壳体3已经成为standard.Curiously然后初始化,而壳体3是压倒性更常见,支持1,2和4但与情况3不兼容的初始化器已成为标准。
因此,如果可能的话,我想从Objective C Gurus得到一个深刻的哲学答案。
来理解的关键(3)是,如果线
if((self = [super init])) {
在C中,每个运营商有返回值,你根本不必使用它。因此,就像3 + 4
返回7一样,运算符=
返回刚分配的相同值。这允许你做有趣的事情是这样吧:
int a, b, c, d;
a = b = c = d = 5;
(这工作,因为运营商有从右到左结合这意味着a = b = 3;
相当于a = (b = 3);
所以b
设置为三个第一,然后。 a
设置为相同的值。)
所以,现在我们可以看到测试
if((self = [super init])) {
是完全一样的
self = [super init];
if (self) {
他们都做同样的事情,虽然。至于首选方案,很多人认为把表达式放入if语句是不好的做法,因为如果你不习惯它,很难注意到。苹果似乎已经与你在他们的模板中列出的第一个例子中解决,还添加了一个编译器第一次警告,如果您尝试做没有愚蠢的双括号if(())
。
所有这三个完成完全相同的任务:调用[super init]
,将它分配给self
(如果super的init返回不同的对象,在某些情况下可能),并测试返回的指针是否为零。如果它是零,则不做任何事情。
示例#1和#3是相同的,它们的语法稍微重新排列。 #2不同之处在于它返回一个明确的值nil
,而#1和#3隐含地这样做。
哪个使用是一个味道的问题。我更喜欢#2,因为它保存了一个凹痕级别(如果可能,我喜欢避免凹痕,因为如果你深入缩进了四五级,它确实很难跟上流程)。
人们并不普遍认同哪一个使用的理由完全一样,他们不同意使用哪种缩进方式(K & R,Allman,GNU,Whitesmith,...):这是个人偏好,并没有改变逻辑。
当我读到作者的文章,其意义远远超出了只是语法糖或例如据说这里的味道:)事项:“奇怪的话,同时案件3绝大多数是比较常见的,支持初始化1,2和4,但是不相容的与壳体3已经成为standard.Curiously然后,当壳体3是压倒性多见,支持1,2和4,但不兼容与壳体3已经成为标准初始化“。 – user310291 2012-03-04 11:28:34
@ user310291:三个变种你引用的所有支票'nil',但是从你所引用的文章段落是关于什么的'[超级初始化]'可以退货。你所引用的三种变体在这里的表现完全相同。为了“解决”这个问题,作者提出了一个新的变体,它将'[super init]'的返回值存储在一个变量中,并将其与(仍然不变)'self'进行比较。所以对于你所引用的三种变体,它真的*是一种味道和语法问题。他们都表现完全一样。 – DarkDust 2012-03-04 12:32:13
他认为[超级初始化]可以返回4个案例,而语法3只能处理3个案例,而它不能处理可能相当频繁的第四种情况。所以这不是品味的问题:这是一个考虑到所有例外的问题,否则你的应用程序不健壮,你不同意吗? – user310291 2012-03-04 13:20:21
如果你有一个变量并没有==,!=,>或类似的东西表达的将是真正的,如果你的变量(在这种情况下,一个指向对象)不为0,这意味着,如果你的指针唐没有指向任何东西。零和NULL为0定义的,所以你可以写
if ((self = [super init]) != nil) {}
或
if ((self = [super init]) != NULL) {}
或
if ((self = [super init]) != 0) {}
或者干脆
if ((self = [super init])) {}
了。
非常感谢,非常清楚,我不能投票第二个好答案:) – user310291 2012-03-05 20:14:42
我也喜欢额外的“房间”使用过于冗长通过不提供,很少直观......坦白地说丑陋语法我在苹果公司的代码见/城镇周围,等...
-(id) init { if (self != super.init) return nil; ...
我可能是溺水的婴儿 - 并导致老帅哥印度人在这个过程中哭 - 但我只是坚持这一切一行 ...和记得return self;
AOK为止!
至于你关于Cocoa with Love的问题,我相信他在谈论罕见的情况,其中'[super init]'返回超类的单例实例,在这种情况下,他不想重写实例变量目的。就我而言,这更像是一种学术上的好奇心,而不是你需要担心的任何事情。 – joerick 2012-03-04 11:49:27
谢谢我现在更好地理解3的语法,所以我给你正确的答案,因为这是我首先提出的问题。尽管如此,他认为[超级初始化]可以返回4个案例,而语法3只能处理3个案例,而不处理可能相当频繁的第四个案例。所以这不是品味的问题:这是一个考虑到所有例外的问题,否则你的应用程序不健壮,你不同意吗? – user310291 2012-03-04 13:21:03
在Cocoa中这是一个非常罕见的情况,你想要继承这些会导致问题的对象之一。这些示例是类集群或单例对象。至少,我可以想到没有理由继承一个单身人士,而不用另外引用单身人士。至于继承类集群,通常在Cocoa中,我们更喜欢[对象组合](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html# // apple_ref/doc/uid/20000154-397934),而不是继承。 – joerick 2012-03-04 13:35:06