2010-09-11 55 views
0

我想了解關鍵字的使用self假設我有兩個類,一個叫做 AppDelegate,另一個叫Photo。照片是我在MVC範例中的「模型」類,AppDelegate是控制器。下面的Photo類的init方法。誰是自我指涉?誰是自我指涉?

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

    } 

    return self; 
} 

回答

4

self是收到該消息的對象。在實例方法中,它是接收消息的實例;在類方法中,它是接收該消息的類。

所以,在initself是你初始化,實例的實例的東西發送的init消息,可能是(希望)從alloc收到後立即。

如果你犯了一個有用的構造方法,比如這個:

//Returns a new, autoreleased Foobar instance. 
+ (id) foobar 

這是一個類的方法,所以在這個方法中,self將參考Foobar類:

{ 
    return [[[self alloc] init] autorelease]; 
} 

實現:

  1. 發送alloc消息給self(全班);假設你沒有覆蓋alloc(你通常不會),它會觸及NSObject的實現,它會通過創建並返回一個未初始化的實例來進行響應。
  2. 向該實例發送init消息;該消息將觸發你的實例方法,該方法調用super,不管初始化是否必要,並返回self(其中init是實例)。
  3. 向該實例發送autorelease消息;再次,你通常不會重寫這個,所以它碰到NSObject的實現,它將實例添加到最近的autorelease池並返回它。
  4. 最後,返回新分配,初始化和自動釋放的實例。
+0

我終於明白了這個概念。非常感謝Hosey先生:D – lampShade 2010-09-11 03:11:47

0

在您的示例代碼中,**self**指的是您已定義init的對象的實例。它類似於C++中的'this'。

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實際上只是一個說法。

+0

如果用'objc_msgSend'替換「'Foo_doSomething'」,那正是編譯器所做的。 ☺ – 2010-09-11 04:32:30

+0

@Peter Hosey雖然有更多的魔法參與。 'objc_sendMsg'必須查找對象類的選擇器。 – zneak 2010-09-11 04:54:41

+0

zneak:嗯?沒有類的選擇器,並且該方法的選擇器被編譯器傳入(這是第二個參數,就像它的方法實現一樣)。 – 2010-09-11 05:11:23