我偶然发现了这篇文章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不兼容的初始化程序已经成为标准。然而,案例3非常普遍,支持1,2的初始化程序和4但与案例3不相容已成为标准。
所以如果可能的话,我想从Objective C Gurus那里得到一个深刻的哲学答案。
答案 0 :(得分:5)
所有这三个完成完全相同的任务:调用[super init]
,将其分配给self
(如果super的init返回一个不同的对象,在某些情况下可能会返回)并测试是否返回指针是零。如果是零,请不要做任何其他事情。
示例#1和#3相同,只是稍微重新排列了语法。 #2的不同之处在于它返回显式值nil
,而#1和#3则隐式地这样做。
使用哪个是品味问题。我更喜欢#2,因为它节省了一个缩进级别(如果可能的话,我喜欢避免缩进,因为如果你有四或五级深度缩进,那么真的很难跟上流程。)
人们并不普遍同意使用哪一个是因为他们无法同意使用哪种缩进方式(K& R,Allman,GNU,Whitesmith,......):它是个人偏好并且不会改变逻辑
答案 1 :(得分:5)
理解(3)的关键是if行
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
首先设置为3,然后a
}设置为相同的值。)
所以现在我们可以观察到测试
if((self = [super init])) {
与
完全相同self = [super init];
if (self) {
但是,他们都做了完全相同的事情。至于首选方案,很多人认为将表达式放入if语句是不好的做法,因为如果你不习惯它就很难注意到。 Apple似乎已经确定了你在模板中列出的第一个例子,并且如果你试图在没有愚蠢的双括号if(())
的情况下尝试这样做,也会为第一个添加编译器警告。
答案 2 :(得分:1)
如果您有变量且没有==,!=,>或类似的东西,如果你的变量(在这种情况下是指向一个对象的指针)不是0,表达式将是真的。这意味着如果你的指针没有指向任何东西。 nil和NULL定义为0,因此您可以编写
if ((self = [super init]) != nil) {}
或
if ((self = [super init]) != NULL) {}
或
if ((self = [super init]) != 0) {}
或只是
if ((self = [super init])) {}
太
答案 3 :(得分:0)
我也更喜欢 NOT 使用过于冗长的所提供的额外“空间”,很少直观......而且坦率地说丑陋的语法我请参阅Apple的代码/城镇等...
-(id) init { if (self != super.init) return nil; ...
我可能会溺水婴儿 - 导致英俊的老印第安人在这个过程中哭泣 - 但我只是坚持一行 ...并且记住 {到目前为止{1}} AOK!