2011-03-03 57 views
0

書「iPhone程序。大書呆子牧場指南」列舉了以下方法(第96頁)使用星號的在變量名

(void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *) views { 
    MKAnnotationView *annotationView = [views objectAtIndex:0]; 
    id <MKAnnotation> mp = [annotationView annotation]; 
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 250, 250); 
    [mv setRegion:region animated:YES]; 
} 

我,因爲星號的使用混淆。

ObjectType variableName = [object message]; 

問題:

  1. 在第一種情況一個星號先於變量名,但不是在以「MKAnnotationView」和一個可以以抽象的方式由下式表示的以下開始的行第二。爲什麼?
  2. 在使用星號的情況下,不應該是分配給nil的指針嗎?

謝謝。

回答

0

ObjectType通常是類似於「指向MKAnnotationView」的指針,它在Objective-C中表示,就像它在C:「MKAnnotationView *」中一樣。異常包括「id」類型,各種整數和浮點類型(包括它們的typedef),枚舉(實際上是整數類型)以及一些小結構(如CGRect)。

+1

id實際上是一個指向objc_object結構的指針。 – Max 2011-03-03 01:49:28

+0

@Max:當然,如果你想進入Objective-C的C級實現。 – Anomie 2011-03-03 01:54:42

3

我傾向於認爲它是什麼變量類型需要星號,而不是什麼變量名稱需要星號。目標C不允許在棧上分配的對象,像這樣:

// Declare an NSObject. Won't work. 
NSObject myObject; 

相反,所有對象必須動態地分配使用指針像這樣的堆:

// Declare a pointer to an NSObject. Will work. 
NSObject* myObject = [[NSObject alloc] init]; 

id是一個特殊的Objective C關鍵字的意思就是「指向某個Objective C對象的指針」。這可能會或可能不會從NSObject繼承,並且是動態類型的。什麼是重要的是要注意的是,雖然沒有星號,這仍是一個指向對象:

// Same as before. Will work. 
id myObject = [[NSObject alloc] init]; 

唯一的區別是,編譯器有沒有什麼myObject的信息。

作爲結束語,id <MKAnnotation>與常規的id完全相同,但是它爲編譯器提供了一些額外的信息。閱讀它作爲「一個指向某個Objective C對象的指針,其行爲類似於MKAnnotation」。 MKAnnotation,在這種情況下,是一個協議的名稱,它的所需方法是聲明特定的id來實現。

1

id已被定義爲指向結構的指針。如果您在objc.h看看它的定義,你會說id被定義爲,

typedef struct objc_object { 
    Class isa; 
} *id; 

因爲它已經是一個指向objc_object,您可以創建對象的指針,而無需使用星號,

id myObject; 

也說一個對象是類型id給編譯器絕對沒有關於對象的信息,除了它的類來自isa屬性。

在另一方面的NSObject被定義爲,

@interface NSObject <NSObject> { 
    Class isa; 
} 

要創建一個指針的NSObject或它的子類(如MKAnnotationView)中的一個對象時,你會聲明爲,

NSObject *myObject; 
MKAnnotationView *myObject; 

我們在這裏放上星號來表示它是一個指針。

指定類型旁邊的協議爲編譯器提供了靜態類型檢查的更多信息。

您應該看看這article簡要介紹idNSObject之間的區別。爲了深入瞭解,請在Objective-C運行時檢查此article