假设我创建了我的类及其init方法.为什么我应该调用并返回init分配给self 的超类的值?它涉及哪些案例?
我会很感激为什么我需要Cocoa超类和非Cocoa的例子.
Jer*_*myP 46
你的意思是为什么
self = [super init];
Run Code Online (Sandbox Code Playgroud)
而不是
[super init];
Run Code Online (Sandbox Code Playgroud)
两个原因:
编辑回应迈克尔的评论:
我能理解为什么我需要保存并返回[super init].但它只是惯例和好看使我们使用self作为临时变量来传递结果吗?
否.实例变量是相对于自指针访问的,因此在下面中:
-(id) init
{
self = [super init];
if (self != nil)
{
myBoolIvar = YES;
// The above is an implicit version of self->myBoolIvar = YES;
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
自我显然必须指向正确的记忆块,即你将要返回的记忆.
另一点是,如果超级init返回不同的类实例,那么该行之后的其余代码甚至可能没有意义,导致内存泄漏和崩溃,甚至没有谈论从该类实例化的对象.
这可能是个问题.如果我继承了NSNumber并且[super init]决定返回一个NSString(它可以 - 没有什么可以阻止它)那显然是一场灾难.无论来自-init的超级回报必须与子类"兼容",从而为ivars提供空间并进一步细分,或者这是一个可怕的错误(当然,除非记录问题).所以,一般来说,你不必担心检查课程.但是,请阅读文档.例如,请参阅NSString文档中有关子类化NSString的部分.
Jom*_*oos 26
我知道我的答案有点晚了,但我不能阻止自己发布一个链接,我发现这个链接对于清除我对这个问题的疑虑非常有用.
Matt Gallagher:当你将[super init]分配给自己时,这是什么意思?
编辑:根据评论,这里是链接的基本要点
要理解为什么self=[super init];我们需要考虑很多要点.让我们一个一个地解决它.
什么是 self
每个方法都有两个隐藏参数:self和_cmd.所以方法调用
- (id)initWithString:(NSString *)aString
Run Code Online (Sandbox Code Playgroud)
由编译器更改为这样的函数调用
id initWithString(id self, SEL _cmd, NSString *aString);
Run Code Online (Sandbox Code Playgroud)
我们为什么需要自己?
实际情况是编译器使用该self参数来解析对方法内的实例变量的任何引用.
假设我们有一个方法,setValueToZero并且value是它所属的类的实例变量,然后是实现
- (void)setValueToZero
{
value = 0;
}
Run Code Online (Sandbox Code Playgroud)
将由编译器转换为这样的函数
void setValueToZero(id self, SEL _cmd)
{
self->value = 0;
}
Run Code Online (Sandbox Code Playgroud)
调用self时是否已经有值init?
以下是典型对象创建和初始化的示例.
[[MyClass alloc] initWithString:@"someString"]
Run Code Online (Sandbox Code Playgroud)
在这里,当我们进入initWithString方法时,self将新分配的对象作为其值(即,返回值[MyClass alloc]).实际上,几乎可以保证它是正确的最终值.
为什么self = [super init];?
这是因为[super init]被允许做以下三件事之一:
self使用初始化的继承实例值返回自己的接收器(指针不会更改).nil,表示失败.在第一种情况下,赋值对此没有影响self.在第三种情况下,初始化失败,self设置为nil并返回.
分配的原因self是第二种情况.考虑以下
- (id)initWithString:(NSString *)aString
{
self = [super init];
if (self)
{
instanceString = [aString retain];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
我们希望转换自
instanceString = [aString retain];
Run Code Online (Sandbox Code Playgroud)
至
self->instanceString = [aString retain];
Run Code Online (Sandbox Code Playgroud)
采取正确的价值,因此我们必须改变价值self.
何时会[super init]返回不同的对象?
在下列情况之一
[NSNumber numberWithInteger:0]始终返回全局"零"对象)除了最后一种情况之外,如果返回的对象发生更改,则继续初始化返回的对象是错误的 - 返回的对象已经完全初始化,并且不再需要与您的类相关.因此,更好的init方法如下
- (id)initWithString:(NSString *)aString
{
id result = [super init];
if (self == result)
{
instanceString = [aString retain];
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
结论
你并不需要分配[super init]到self使大多数类的工作.在一些不起眼的案例中,这实际上是错误的.
那么我们为什么还要继续分配self呢?它是初始化程序的传统模板,虽然在某些情况下它是错误的,但在其他已经编写过的方法中,它是正确的.
| 归档时间: |
|
| 查看次数: |
22948 次 |
| 最近记录: |