use*_*291 3 initialization objective-c nsobject ios
我偶然发现这篇文章在Objective-C中我为什么要检查self = [super init]是不是nil?
我能理解这种语法:
- (id)initWithString:(NSString *)aString
{
self = [super init];
if (self)
{
instanceString = [aString retain];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
或者这个语法:
- (id)init;
{
if (!(self = [super init]))
return nil;
// other stuff
return self;
}
Run Code Online (Sandbox Code Playgroud)
但我仍然不理解"标准"模板语法
- init {
if((self = [super init])) {
// set up instance variables and whatever else here
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
有人可以尽可能清楚地告诉(3)与(1)或(2)相比更多或更少吗?我读到的都是如此令人困惑(为什么人们不能同意纯粹技术性的东西似乎是政治:))
然而,当我读到作者的文章时,我可以模糊地理解它远不仅仅是语法糖辩论或品味问题.例如,据说:
奇怪的是,虽然案例3非常普遍,但支持1,2和4但与案例3不兼容的初始化程序已经成为标准.然而,案例3绝大多数情况下,初始化程序支持1,2和4但是与案例3不相容已成为标准.
所以,如果可能的话,我想从Objective C Gurus那里得到一个深刻的哲学答案.
所有这三个都完成了完全相同的任务:调用[super init],分配给它self(如果超级init返回一个不同的对象,在某些情况下可能),并测试返回的指针是否为零.如果是零,请不要做任何其他事情.
示例#1和#3是相同的,它们只是稍微重新排列了语法.#2的不同之处在于它返回显式值nil,而#1和#3则隐式地这样做.
哪个使用是品味问题.我更喜欢#2,因为它节省了一个缩进级别(如果可能的话,我喜欢避免缩进,因为如果你有四或五级深度缩进,那么真的很难遵循这个流程).
人们并不普遍同意使用哪一个是因为他们无法同意使用哪种缩进方式(K&R,Allman,GNU,Whitesmith,......):它是个人偏好并且不会改变逻辑.
理解(3)的关键是if行
if((self = [super init])) {
Run Code Online (Sandbox Code Playgroud)
在C中,每个操作符都有一个返回值,您不必使用它.因此,就像3 + 4返回7一样,运算符=返回刚刚分配的相同值.这允许你用它来做这样有趣的事情:
int a, b, c, d;
a = b = c = d = 5;
Run Code Online (Sandbox Code Playgroud)
(这工作,因为运营商有从右到左的关联性.这意味着,a = b = 3;以相当于a = (b = 3);因此b被设置为三个第一,然后a设置为相同的值.)
所以现在我们可以观察到这个测试
if((self = [super init])) {
Run Code Online (Sandbox Code Playgroud)
与...完全相同
self = [super init];
if (self) {
Run Code Online (Sandbox Code Playgroud)
但他们都做了完全相同的事情.至于首选方案,很多人认为将表达式放入if语句是不好的做法,因为如果你不习惯它就很难注意到.Apple似乎已经确定了你在他们的模板中列出的第一个例子,并且如果你试图在没有愚蠢的双括号的情况下尝试这样做,也为第一个添加了编译器警告if(()).