I've been wondering why Apple uses data types in Core Foundation that are typedef'd to a pointer type while in Cocoa they are not.
As an example, you would reference a UIColor object like UIColor *
while a reference to a CGColor object would be CGColorRef
? Or NSURL *
and CFURLRef
? Why not just always use CGColor *
and CFURL *
? Or conversely, why no UIColorRef
or NSURLRef
types, since you never access a UIColor
or NSURL
directly anyway?
Or for example, why is it id
and not id *
, since it is actually a pointer and can in fact be typecast to void *
?
Specifically, is there some reason Apple had a habit of doing this in their older frameworks, but stopped doing it in Cocoa? Is it simply a matter of style?
What Matt said, but there is a bit more to it.
The typedefs in the C based APIs also allow the implementation details to be hidden. For example, you can have the following without ever defining the __CFURL structure in a public header.
typedef __CFURL *CFURLRef;
Objective-C has long had these kinds of features in the form of categories and, recently added, the ability to move instance variable declarations out of the header file. Expect that, over time, you will see all instance variables removed from the public header files in the SDK.
Note that the Cocoa frameworks long, long, pre-dated CoreFoundation.
As for why id
is used instead of id *
, that dates back to when Objective-C was first created in the early 1980s. Specifically, the notion of the language was that you would build "software integrated circuits" that could be "plugged together" like real ICs. The goal was to keep the C bits around as implementation details and, ideally, not exposed in your APIs.
As for why you end up with NSString *
instead of NSString
, that is largely exactly because of the C underpinnings of the language. I wrote a fairly detailed answer to a slightly different SO question that is relevant.
You'll probably also find this answer relevant, too.