我一直在想,为什么苹果在Core Foundation中使用的数据类型是指向指针类型的typedef,而在Cocoa中则不是。
举个例子,您会引用像UIColor *
这样的UIColor对象,而对CGColor对象的引用是CGColorRef
?还是NSURL *
和CFURLRef
?为什么不总是使用CGColor *
和CFURL *
呢?或者反过来说,既然您从未直接访问过UIColor
或NSURL
,为什么没有UIColorRef
或NSURLRef
类型?
或者例如,为什么它是id
而不是id *
,因为它实际上是一个指针,实际上可以被类型转换为void *
?
具体来说,苹果有在旧框架中这样做的习惯,但在Cocoa中停止了这样做,这是有原因的吗?这只是一个风格问题吗?
马特说了什么,但还有更多。
基于C的API中的typedef还允许隐藏实现细节。例如,您可以拥有以下内容,而无需在公共标头中定义__CFURL结构。
typedef __CFURL *CFURLRef;
Objective-C长期以来一直以类别的形式具有这类功能,最近还添加了将实例变量声明从头文件中移出的功能。预计随着时间的推移,您将看到从SDK的公共头文件中删除的所有实例变量。
请注意,Cocoa框架很长,很长,早于CoreFoundation。
至于为什么使用id
而不是id *
,可以追溯到20世纪80年代初Objective-C首次创建的时候。具体来说,该语言的概念是,你可以构建"软件集成电路",可以像真正的IC一样"插在一起"。目标是保留C位作为实现细节,理想情况下,不在API中公开。
至于为什么最终使用NSString *
而不是NSString
,这在很大程度上正是因为该语言的C基础。我写了一个相当详细的答案,回答了一个与SO略有不同的相关问题。
你可能也会发现这个答案很有意义。
NSURL*
与CFURLRef
的区别很大程度上是因为它只是一种编码风格。Cocoa是一个Objective-C API,Objective-C中的一般风格是没有typedef,而CoreFoundation是一个C API,它的一般风格就是使用typedef。这在很大程度上取决于编码风格。
id
与id*
——我不完全确定,但我猜这是历史性的,他们只是想让基础"对象"没有*
。不过,我不确定这件事的历史。但这也只是一种风格。