在变量名中使用星号

时间:2011-03-03 01:25:38

标签: iphone objective-c

“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];
}

由于星号的使用,我很困惑。以“MKAnnotationView”开头的行和下一行可以通过以下方式以抽象方式表示:

ObjectType variableName = [object message];

问题:

  1. 在第一种情况下,星号位于变量名称前面,但不在第二种情况下。为什么?
  2. 在使用星号的情况下,不应该是指定为nil的指针吗?
  3. 感谢。

3 个答案:

答案 0 :(得分:3)

我倾向于将其视为变量类型需要星号,而不是变量名称需要星号。 Objective 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完全相同,但有一些编译器的额外信息。将其读作“指向一些行为类似于MKAnnotation的Objective C对象的指针”。在这种情况下,MKAnnotation是一个协议的名称,其声明要实现特定id的必需方法。

答案 1 :(得分: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

答案 2 :(得分:0)

ObjectType通常类似于“指向MKAnnotationView的指针”,它在Objective-C中表示,就像在C:“MKAnnotationView *”中一样。例外包括“id”类型,各种整数和浮点类型(包括它们的typedef),枚举(实际上是整数类型),以及一些像CGRect这样的小结构。