“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];
问题:
感谢。
答案 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,以简要了解id
和NSObject
之间的差异。要深入理解,请在Objective-C运行时检查此article。
答案 2 :(得分:0)
ObjectType通常类似于“指向MKAnnotationView的指针”,它在Objective-C中表示,就像在C:“MKAnnotationView *”中一样。例外包括“id”类型,各种整数和浮点类型(包括它们的typedef),枚举(实际上是整数类型),以及一些像CGRect这样的小结构。