3

我有一个关于在 Objective-C 中使用星号的问题。明确一点:我了解指针是什么以及程序 C 中的所有内容。不过我想知道两件事:

1) 为什么所有(引用)Objective-C 对象都是指针?为什么不是普通变量?(即 NSArray 数组 = [[NSArray alloc] init];)

2)为什么在调用方法时省略星号?

谢谢!

4

2 回答 2

20

1) 为什么所有(引用)Objective-C 对象都是指针?为什么不是普通变量?(即 NSArray 数组 = [[NSArray alloc] init];)

暂时将 Objective-C 对象想象成一个美化的结构。

NSArray array;在本地范围内将是堆栈上“分配”的对象。 NSArray *array;表示由一大块内存支持的对象,通常从堆中分配。

很久很久以前,Objective-C 决定不支持堆栈上的对象。大多数情况下,因为这样做会使内存管理变得一团糟(主要-retain是堆栈上的某些东西根本没有任何意义)。

由于 Objective-C 被设计为 C 的纯超集,并且与 C++ 不同,它不会尝试修改 C 的基本行为,因此将其包含*在其中似乎很自然。

请注意,这id打破了这一点,但id也是一种完全通用的类型。事实上,堆栈中可能有 Objective-C 对象。在 Snow Leopard 中,块实际上是 Objective-C 对象,它们确实从堆栈开始。但是,不支持您在堆栈上创建自己的对象。

2)为什么在调用方法时省略星号?

因为您没有取消引用指向对象的指针,并且指向对象的指针在方法实现本身中至关重要。当你说...

[anArray objectAtIndex: 5];

...完全等同于写作...

objc_msgSend(anArray, @selector(objectAtIndex:), 5);

...当您实施所述方法时....

- (id) objectAtIndex: (NSUInteger) anIndex;

...完全等同于实现这个C函数...

id object_at_index(id self, SEL _cmd, NSUInteger anIndex) { ... }

也就是说,Objective-C 方法实际上只是一个接受两个或多个参数的 C 函数。事实上,您可以将这行代码粘贴到任何方法实现中,它会“正常工作”:

NSLog(@"method %@", NSStringFromSelector(_cmd));
于 2010-01-10T04:06:56.730 回答
2

Objective-C 语言将尽可能多的决策从编译时和链接时推迟到运行时。只要有可能,它就会动态地执行诸如创建对象和确定调用什么方法之类的操作。
所以如果它允许

NSArray array = [[NSArray alloc] init];  

在一种方法中,编译器必须在编译时知道 NSArray 的大小。

于 2010-01-10T04:23:13.070 回答