在正常情况下,当您发送+alloc
到一个类时,它会返回该类的归零实例。它已经在以下意义上进行了初始化:a)它是该类的正确实例,并且 b)所有实例变量都被清零(数字类型为 0,C 指针为 NULL,对象为 nil 等)。但是,没有对新创建的实例应用额外的初始化行为——这是初始化器的工作,-init
是其中最常见的。特别是,如果您的类从NSObject
then继承,则[super init]
不会触及新创建的实例。因此,在您在问题中发布的代码中,
- (在类外)
+alloc
被发送到MyClass
,它返回一个归零的实例。特别ivar_
是 0
- (类外)
-init
被发送到新创建的实例
ivar_ == 12345
因为 中的赋值-init
,可以改写为self->ivar_ = 12345
。此时,self
指向返回的实例+alloc
[super init]
被发送,ivar_
没有被触及,因为它的超类 ( NSObject
) 不知道它,并且返回值被分配给self
. 实际上,返回值已经是self
所以没有任何改变
- 因为
self
不同于nil
,NSLog()
所以称为
-init
返回self
现在让我们考虑[super init]
返回一个与返回的实例不同的实例+alloc
:
- (在类外)
+alloc
被发送到MyClass
,它返回一个归零的实例。特别ivar_
是 0
- (类外)
-init
被发送到新创建的实例
ivar_ == 12345
因为 中的赋值-init
,可以改写为self->ivar_ = 12345
。此时,self
指向返回的实例+alloc
[super init]
被发送,它决定释放当前实例并返回一个不同的实例。返回值被分配给self
所以,从当前的角度来看,-init
现在正在处理不同的实例。旧实例已被释放,因此该更改ivar_
丢失。包含决定它应该包含ivar_
的任何内容[super init]
- 因为
self
不同于nil
,NSLog()
所以称为
-init
返回self
,这与创建的实例不同+alloc
您可以使用以下代码对此进行测试。请注意,这只是一个简单的示例来说明我的答案,不应在生产代码中使用它。
#import <Foundation/Foundation.h>
@interface MySuperClass : NSObject
@end
@interface MyClass : MySuperClass
{
@public
int ivar_;
}
@end
@implementation MySuperClass
static MyClass *defaultInstance;
- (id)init
{
if ([self isMemberOfClass:[MyClass class]] && defaultInstance != nil)
{
[self release];
return defaultInstance;
}
return [super init];
}
@end
@implementation MyClass
- (id)init
{
ivar_ = 12345;
if ((self = [super init]))
NSLog(@"ivar_'s value is %d", ivar_);
return self;
}
@end
int main()
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
defaultInstance = nil;
defaultInstance = [[MyClass alloc] init];
NSLog(@"%d", defaultInstance->ivar_); // outputs 12345
defaultInstance->ivar_ = 98765;
NSLog(@"%d", defaultInstance->ivar_); // outputs 98765
MyClass *someInstance = [[MyClass alloc] init];
NSLog(@"%d", someInstance->ivar_); // outputs 98765
if (someInstance == defaultInstance)
NSLog(@"They're the same!");
[pool drain];
return 0;
}
输出是
ivar_'s value is 12345
12345
98765
ivar_'s value is 98765
98765
They're the same!