谁是自我指的?

时间:2010-09-11 02:19:51

标签: objective-c cocoa

我正在尝试理解关键字self的使用让我们说我有两个类叫一个 AppDelegate和一个叫Photo。 Photo是我在MVC范例中的“模型”类,而AppDelegate是控制器。在下面的Photo类的init方法中。谁是自我指的?

-(id) init
{
    if( self = [super init] ){
        [self setCaption:@"Default Caption"];
        [self setPhotographer:@"Default Photographer"];

    }

    return self;
}

3 个答案:

答案 0 :(得分:4)

self是收到邮件的对象。在实例方法中,它是接收消息的实例;在类方法中,它是接收消息的类。

因此,在init中,self是您正在初始化的实例 - 某个事件发送init消息的实例,可能(希望)在从{{ 1}}。

如果你做了一个方便的构造函数,比如:

alloc

这是一个类方法,因此在此方法中,//Returns a new, autoreleased Foobar instance. + (id) foobar 将引用self类:

Foobar

实施:

  1. { return [[[self alloc] init] autorelease]; } (该班级)发送alloc条消息;假设您没有覆盖self(并且通常不会),它将触及NSObject的实现,它将通过创建和返回未初始化的实例来响应。
  2. 向该实例发送alloc条消息;该消息命中您的init实例方法,该方法调用super,执行任何必要的初始化,并返回initself中的实例)。
  3. 向该实例发送init条消息;再一次,你通常不会覆盖它,所以它会触及NSObject的实现,它将实例添加到最近的自动释放池并返回它。
  4. 最后,返回刚分配,初始化和自动释放的实例。

答案 1 :(得分:1)

self是您要向其发送消息的对象。例如,如果您拨打[foo doSomething]之类的内容,则doSomething方法中的self将等于foo。这是传递给方法的隐藏参数。

令人困惑的是self在Objective-C中不是只读的。例如,正如您所看到的,在初始值设定项中,您实际上覆盖了self

if( self = [super init] ){

这是因为[super init]实际上有权返回一个完全不同的对象。但是,您只是更改作为参数传递的变量的值;您没有更改调用方法的范围中的值。

Foo* foo = [[Foo alloc] init];
// ... may be different of...
Foo* foo = [Foo alloc];
Foo* bar = [foo init];

在此示例中,在第二种情况下,foobar实际上可能指向两个不同的对象。 allocinit都返回一个指向对象的指针,从技术上讲,它们可以不同(尽管你唯一想要保留的是init返回,因为alloc的返回值所指向的对象尚未准备好使用)。

如上所述,self实际上是方法接收的两个隐藏参数之一。另一个隐藏的参数名为_cmd,包含用于调用方法的选择器。你很少需要它。

这意味着每当你看到这个:

id bar = [foo doSomethingWithInt:5];

您可以(象征性地)将其解析为类似于此的函数调用:

id bar = Foo_doSomething(foo, @selector(doSomethingWithInt:), 5);

所以self实际上只是一个论点。

答案 2 :(得分:0)

在您的示例代码中,**self**指的是您已定义init的对象的实例。它类似于C ++中的“ this ”。