Objective c Self=[super init]

Objective c Self=[super init],objective-c,Objective C,如果self能够存储基类实例,那么当我们返回self时,它是如何转换为派生实例的。self是一个隐藏的方法参数: // this Objective-C - (id) initWithString:(NSString*)str; // gets implemented like this C function would be - (objc_object*) Foo_initWithString(Foo* self, SEL _cmd, NSString* str); 它是一个指向内存的指

如果self能够存储基类实例,那么当我们返回self时,它是如何转换为派生实例的。

self
是一个隐藏的方法参数:

// this Objective-C
- (id) initWithString:(NSString*)str;

// gets implemented like this C function would be
- (objc_object*) Foo_initWithString(Foo* self, SEL _cmd, NSString* str);
它是一个指向内存的指针(分配有
alloc
),内存已经足够大,可以容纳最派生的对象。派生最多的类调用super的
init
,super也调用其super的
init
,因此层次结构中的每个类都会调用其构造函数

因此,没有任何东西被转换-它只是一个指向已存在对象的指针,您可以返回它(99.9%的时间)或替换另一个对象


注意,还有第二个隐藏参数,选择器
\u cmd
,在本例中等于
@selector(initWithString:)
。如果您需要当前方法名,例如调试日志记录,也可以使用它。

我想您是在问:假设我们有一个基类和一个子类派生。如果
-[Derived init]
调用
-[Base init]
并且
-[Base init]
返回一个不同的实例,那么这个不同的实例不是
Base
的实例,而是
Derived
的实例,因此不合适吗?例如,新对象将不具有
派生的
可能已添加到类中的实例变量

答案是
Base
不允许这样做。如果它替换原始实例,则必须以尊重该原始实例的动态类型的方式进行替换。例如,它可能会执行以下操作:

// Re-allocate with 100 extra bytes
id newSelf = NSAllocateObject([self class], 100, [self zone]);
[self release];
self = newSelf;
// ... continue to initialize ...
return self;
或者,它可以动态地生成原始类的新子类,然后分配该新类的新实例

NSString* newClassName = [NSString stringWithFormat:"%@_DynamicSubclass", NSStringFromClass([self class])];
Class newClass = objc_allocateClassPair([self class], [newClassName UTF8String], 0);
// ... further configure the new class, by adding instance variables or methods ...
objc_registerClassPair(newClass);
id newSelf = [newClass alloc];
[self release];
self = newSelf;
// ... continue to initialize ...
return self;

无论它做什么,它都必须满足一个约束,即新实例适合在旧实例所在的任何位置使用,基于其动态类型。

此处超级实例不指定给派生实例<代码>自我=[super init]就像告诉运行时系统在超类方法选择器表中查找init方法一样。。。在super
-init
方法中,
self
类似于对超类和派生类的支持。在目标c中,在类继承的情况下。。仅复制实例变量。。方法由层次结构中的所有类共享。如果你超控。。你应该做
self=[super init]
;这将导致u使用NSObject
-init
方法。如果我们重写super类中的
-init…
方法,请确保首先调用super
-init…
。这是我的理解。谢谢。

我同意你的观点,赛尔夫能够持有衍生对象。但我的疑问是,如果NSString*tempStr=@“Hello”;NSString*tempStr1=tempStr;在上述情况下,tempStr1和tempStr指向同一位置。类似地,self指向超级实例,但它是如何转换为派生实例的。@user1421041无疑是这样的。但是你想问什么吗?是的。超级实例将如何成为派生实例?@user1421041它们在内存中的布局方式使它们从同一地址开始。指向最派生对象的指针也是指向其所有基类的指针-不需要转换。谢谢,如果您能让我知道它们在内存中的布局,那将非常有用。