I was porting some ObjectiveC
custom UIView
subclasses to Swift
this morning. Wanting to make it more "object oriented", I was following the example of extending CGContext
with methods. E.g.
extension CGContext {
func fillColor(color:UIColor) {
CGContextSetFillColorWithColor(self, color.CGColor)
}
}
Because I was converting the objective C style messages (e.g. -(void) drawOutline: (CGContextRef) cr {...}
) to Swift style ones without paying to much attention (e.g. func drawOutline(cr:CGContextRef) {...}
), I didn't realize at first that I was passing CGContextRef
arguments, but had extended CGContext
(not Ref). But it worked!
What was weirder, was when I changed those CGContextRef
's to just CGContext
's. And it still worked. Not just compiled, but ran and drew correctly. For the fun of it, I changed to extension CGContextRef
. And yet it still continues to work. It's as if Swift is smart enough to boil them down to the same thing. Is it? Or is there something more subtle/cool going on here?
There's nothing particularly magical here. CGContextRef
and CGContext
are just different names for (almost) the same thing. Swift just blurs the typedef for you.
<CoreGraphics/CGContext.h>
typedef struct CGContext *CGContextRef;
See also the Using Swift with Cocoa and Objective-C guide section on Core Foundation:
When Swift imports Core Foundation types, the compiler remaps the names of these types. The compiler removes Ref from the end of each type name because all Swift classes are reference types, therefore the suffix is redundant.
They just chose not to take away the Ref
form of the name, I guess for old timers who are used to typing it :D