Objective-c:关于self = 的问题
我在init方法中看到了self = [super init]
。 我不明白为什么。 不会[super init]
返回超类? 如果我们指出self = [super init]
,我们没有得到self = superclass
?
这是一个示例代码片段
- (id)init { if (self = [super init]) { creationDate = [[NSDate alloc] init]; } return self; }
希望有人能为我澄清这一点。 谢谢。
假设MyClass
是BaseClass
一个子类,调用时会发生以下情况
MyClass *mc = [[MyClass alloc] init];
-
[MyClass alloc]
分配MyClass
一个实例。 -
init
消息被发送到这个实例来完成初始化过程。
在该方法中,self
(这是所有Objective-C方法的隐藏参数)是从步骤1分配的实例。 -
[super init]
使用相同的(隐藏的)self
variables调用[super init]
的超类实现 。 (这可能是你错误理解的观点。) -
在
BaseClass
的init
方法中,self
仍然是MyClass
的同一个实例 。 这个超类init方法现在可以- 做
self
的基础初始化并返回self
,或者 - 放弃
self
并分配/初始化并返回一个不同的对象。
- 做
-
回到
MyClass
的init
方法中:self = [super init]
现在也是- 在步骤1中分配的
MyClass
对象或 - 有些不同。 (这就是为什么要检查和使用这个返回值。)
- 在步骤1中分配的
- 初始化完成(使用由超类init返回的
self
)。
所以,如果我正确地理解你的问题,那么主要的一点是
[super init]
使用self
参数调用init
的超类实现,这是一个MyClass
对象,而不是一个BaseClass
对象。
正如你有问题self = [super init]
if条件中提出了一个具体的含义。
首先[super init]
给出当前正在使用的现有类的超类的初始化。 使用[super init]
给出了超类初始化,它显示了类的对象存在。
现在,当你使用self = [super init]
,意味着你正在将这个类分配给自己,以便进一步利用同一个类。
最后,如果条件是if(self = [super init])
则表示您正在检查类的对象是否存在,以防止应用程序的恶意行为。
我想现在很清楚!
@MartinR有一个非常好的答案。 但你有没有想过为什么“(超级初始化)调用init的超类实现与同一个(隐藏的)自我论证(这可能是你错误理解的观点)。
这是Big Nerd牧场指南第3版,第2章Objective C的摘录,阐明了这一点
“超级怎么样? 通常,当您向对象发送消息时,search该名称的方法将从对象的类中开始。 如果没有这样的方法,search继续在对象的超类中。 search将继续inheritance层次结构,直到find合适的方法。 (如果它到达层次结构的顶部并且没有find方法,则抛出exception。)“
“当你发送消息给super时,你正在向自己发送消息,但是search方法会跳过对象的类并从超类开始。
此代码显示iOS运行时如何执行此任务
objc_msgSendSuper(self, @selector(init));
您声明的每个方法都有两个隐藏的参数:self和_cmd。
以下方法:
- (id)initWithString:(NSString *)aString;
由编译器转换为以下函数调用:
id initWithString(id self, SEL _cmd, NSString *aString);
看到这个链接更多:
http://www.cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html
我会认为它,启动所有的超级variables等,然后你得到初始化您的扩展类variables之前它返回。
[super init]
与[ self superclass_variant_of_init]相同
如果你想发送消息给超类,还有另一种方法(不使用运行时库):
[[self superclass] init];
从Apple的文档 :
由于init …方法可能返回nil或除明确分配的对象之外的对象,因此使用由alloc或allocWithZone返回的实例(而不是由初始化程序返回的实例)是危险的。 考虑下面的代码:
id myObject = [MyClass alloc]; [myObject init]; [myObject doSomething];
上例中的init方法可能已经返回nil,或者可能已经replace了不同的对象。 因为你可以发送消息给nil而不会引发exception,所以除了(可能)debugging头痛之外,前一种情况不会发生。 但是你应该总是依赖初始化的实例,而不是刚刚分配的“原始”实例。 因此,在继续之前,您应该将分配消息嵌套在初始化消息中,并testing从初始化程序返回的对象。
id myObject = [[MyClass alloc] init]; if ( myObject ) { [myObject doSomething]; } else { // error recovery... }
Self = [super init];
根据JAVA, 这意味着一个实例本身的指针,所以对象可以自己消息。
目标C中同样自我的 meainng,
根据JAVA, 超级意味着允许访问基类或父类
目标C中同样超级的 meainng,
现在init实例来完成初始化过程。