首页
学习
活动
专区
圈层
工具
发布

目标
EN

Stack Overflow用户
提问于 2012-12-15 02:17:04
回答 1查看 869关注 0票数 2

新的目标-c。编写了一个代码片段,以更好地理解init机制,最后提出了几个问题。

代码语言:javascript
复制
@implementation MyClass    
    -(id) init
    {
        if (self) {
            i = 5;
            NSLog(@"self before init - %@ %p i=%d",[self className], &self, i);
        } else {
            NSLog(@"self is null???");
        }

        id someClass = [super init];
        NSLog(@"the result of super-init - %@ %p",[someClass className], &someClass);

        self = [super init];
        if (self) {
            NSLog(@"self after init - %@ %p %d",[self className], &self, i);
        } else {
            NSLog(@"self is null???");
        }

        return self;
    }

i是一个私有实例变量int

结果如下:

代码语言:javascript
复制
2012-12-14 18:01:26.403 Init[1621:303] self before init - MyClass 0x7fff5fbff848 i=5
2012-12-14 18:01:26.405 Init[1621:303] the result of super-init - MyClass 0x7fff5fbff838
2012-12-14 18:01:26.405 Init[1621:303] self after init - MyClass 0x7fff5fbff848 5

真正令我惊讶的是,某个类的类名是MyClass

  • NSObject如何知道如何返回子类实例(不只是类型匹配,它是完全相同的对象)?

我知道,在调用init之前多次调用init并初始化实例变量并不是很好的形式,但我只是在做实验。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-15 02:33:34

您确实需要使用标准模式(或多或少):

代码语言:javascript
复制
-(id)init {
    self = [super init];
    if (self) {
        // Do initialization stuff
    }
 }

您的类子类为其他类。对super init的调用运行超类的init例程。如果没有它,您的类就无法正确初始化,可能会发生奇怪的故障。(然而,两次调用super init可能是不明智的,因为这可能会产生不良副作用。)

在某些情况下,您不会调用super init,而是会在您自己的类中调用init的一个版本。基本上,如果您有initWithJunk:init,您可以让initWithJunk:调用[self init]而不是[super init],这样self init所做的事情就可以完成,而不必在initWithJunk:中复制。

如果您编写了一个将init...方法添加到现有类的“类别”--您必须调用某些版本的[self init]以确保基类的初始化器运行,这一点尤其重要。

请理解,super init方法(通常)不是用新实例替换现有实例,而是初始化属于超类的实例字段。从super init调用中接收"self“值的原因有两方面:

  1. init例程可以在发生某种错误时返回nil
  2. 在某些(罕见的)特殊情况下,init例程可能会将提供的实例替换为不同的实例(例如缓存的版本)。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13888702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档