Swift: Notable Beta 4 Changes
Prayers answered, denied
Here are some of the more notable Swift changes as of Beta 4:
Access Control
The new access control keywords are available:
modifier | |
---|---|
private | can only be accessed from the source file where defined |
internal | can only be accessed from the current target where defined |
public | can be accessed anywhere, including any context that imports the module |
The default is internal
, which means most source code won't need to bother with the modifiers unless you want to mark class variables private
for encapsulation. Frameworks will only expose public
members so they need to be a bit more careful. Another thing to note is private
members are not exposed to Objective-C unless you explicitly tag them with @objc
.
The example from the release notes:
// An example class in a framework target.
public class ListItem: NSObject {
public var text: String
public var isComplete: Bool
// Readable throughout the module, but only writeable from
// within this file.
private(set) var UUID: NSUUID
public init(text: String, completed: Bool, UUID: NSUUID) {
self.text = text
self.isComplete = completed
self.UUID = UUID
}
func refreshIdentity() {
self.UUID = NSUUID()
}
// Must be public because it overrides a public method
// and is itself part of a public type.
public override func isEqual(object: AnyObject?) -> Bool {
if let item = object as? ListItem {
return self.UUID == item.UUID
}
return false
}
}
Overall I like it; this system reminds me a lot of C#. The only question I have is regarding derived class visibility - are private
members visible or not? Should they be? That's the main difference - C# allows you to specify things are only accessible to this class and derived classes with protected
, as opposed to completely hidden from anyone else with private
.
Keywords
A number of attributes are now just plain keywords so @final
-> final
, @lazy
-> lazy
, @optional
-> optional
, @required
-> required
. The docs indicate that some others will get the same treatment in future betas like @class_protocol
and @prefix
. Curiously, they didn't mention @objc
, but later on in the docs I spotted some declarations using it without the @
so give things a try and see what works.
Landmarks
This is a long missed feature and I'm glad to see Xcode finally adopt it; obviously other people have wanted it forever too because the radar number is down in the 14000000 range.
Xcode will now recognize //MARK:
, //TODO:
, and //FIXME
as landmarks and display them in the jump bar. Hurray!
REPL Improvements
The REPL now supports the entire language so you can declare operators and the like. It also now preserves history across sessions so you can up-arrow and get your code back after a crash or restart.
The REPL also has better multi-line editing. This one drove me crazy, making it impossible to arrow-up or paste and edit some declarations
Numbers, Numbers, Numbers
NSUInteger
now maps to Int
in system frameworks, but to UInt
in user code. This one is interesting and is probably to avoid the massive amount of casting required where tons of enums and constants don't match the type signatures of the methods that use them. A reasonable compromise in my opinion.
Another very welcome change is CGFloat
now wraps either float
on 32-bit or double
on 64-bit, making interacting with CoreGraphics
much easier (since Swift does not do automatic promotion of numeric types)
Interop Changes
CString
has been removed. This is a massive improvement! I spent way too much time trying to map all the variations of [CChar]
, UnsafePointer<Int8>
, and CString
. Now Swift just imports these as pointers to Int8
, except macros that expand to strings just come in as regular Swift String
literals.
Dreaded Variable Size Type
You can now use variable size generics so long as the class isn't exposed to Objective-C. This means you can go delete all your array workarounds and just use class Box<T> { var value:T? }
.
One curious thing is they say if you still want to use the class with Objective-C you can continue using the array workaround: class Box<T> { var value:[T] }
. The problem is Objective-C doesn't support generics so how can you expose the class to Objective-C at all? Perhaps some kind of generics support is coming to Objective-C? Very curious.
Other Fixes
true
and false
aren't library constants anymore; they are built-in Boolean
literals and the BooleanLiteralConvertible
protocol allows you to define types that support boolean logic properly. Some stuff was already sorta doing this (e.g. a non-null UnsafePointer<T>
would evaluate to true
in an if
statement), but now it's official and usable by our own code.
The OS X playground is now sandboxed (so no accidentally deleting everything!), but only data saved to the ~/Documents/Shared Playground Data
shared location is accessible between runs or between playgrounds. Watch out though - the iOS playground is not sandboxed yet.
This blog represents my own personal opinion and is not endorsed by my employer.