在正常情况下,当您发送+alloc到一个类时,它会返回该类的归零实例。它已经在以下意义上进行了初始化:a)它是该类的正确实例,并且 b)所有实例变量都被清零(数字类型为 0,C 指针为 NULL,对象为 nil 等)。但是,没有对新创建的实例应用额外的初始化行为——这是初始化器的工作,-init是其中最常见的。特别是,如果您的类从NSObjectthen继承,则[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!