Post on 10-May-2015
Swift
Denis Lebedev, iOS @ Yandex
Agenda
• Introduction
• Objective-C bridging
• Good-to-know features
• “Where can I Swift?”
Swift
Chris Lattner, Swift creator
Swift
• Multi-paradigm
• Static, inferred typing
• Bridged with Objective-C
• No pointers
–Someone at WWDC Keynote
It’s like “Objective-C without C.”
Swift features
• Namespacing*
• Generic classes & functions
• Named/default parameters
• Functions are first class citizens
• Optional types
Optionals
• Used in situations where value may be absent
• Alternative for obj-c nil passing
• works with any type
Optionals
- (NSInteger)indexOfObject:(id)object;
Optionals
func indexOf(object: AnyObject) -> Int?
Forced unwrapping
let result :Int? = indexOf(bar);
let s = String(result) //error
let s = String(result!)
Optional binding
if let r = result {
let s = String(r)
} else {
// r is nil
}
Classes, structs, enums
• Classes passed by reference, structs - by value
• Using a struct has no runtime penalty
• All scalars and even Bool are structs
Collections
• Array, Dictionary
• Collections are structs
• Implicitly bridged to Cocoa collection types
Built-in immutability
var b = 3
b += 1
let a = 3
a += 1 // error
Dictionary immutability
let d = ["key0": 0]
d["key"] = 3 //error
d.updateValue(1, forKey: "key1") //error
Array immutability
let c = [1, 2, 3]
c[0] = 3 // success
c.append(5) // fail
Array immutability
let c = [1, 2, 3]
c[0] = 3 // success
c.append(5) // fail
It’s a bug:
https://devforums.apple.com/message/971330#971330
Extensions
• extends any named type (struct, enum, class)
• structures code
Extensions struct Foo {
let value : Int
}
extension Foo : Printable {
var description : String {
get {return "Foo"}
}
}
extension Foo : Equatable {
}
func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.value == rhs.value
}
What Swift is missing
• Preprocessor
• Exceptions
• Access control *
• KVO, KVC
• Compiler attributes (platforms, deprecations, etc.)
• performSelector: is unavailable
Objective-C bridging
• Call Obj-c from Swift
• Call Swift from Objc with limitations
• Call CoreFoundation types directly
• C++ is not allowed (should be wrapped in Objc)
• Subclassing Swift classes not allowed in Objc
Objective-C bridging
• NSArray < - > Array
• NSDictionary < - > Dictionary
• NSNumber - > Int, Double, Float
Objective-C bridging
@objc class Foo {
init (bar: String) { /*...*/ }
}
Objective-C bridging
@objc(objc_Foo)
class Foo {
@objc(initWithBar:)
init (bar: String) { /*...*/ }
}
Objective-C bridging
Foo *foo = [[Foo alloc] initWithBar:@"Bar"];
Objective-C bridging
func tableView(tableView: UITableView!,
cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Objective-C bridging
• All object types are mapped as implicitly
unwrapped optionals (T!)
• All ‘id’ types are mapped as ‘AnyObject’
Swift internals
• Swift objects are Obj-c objects
• Implicit root class ‘SwiftObject’
• Ivars type encoding is stored separately
• Method’s vtable
Name mangling
• Swift keeps function metadata encoded in
function symbols
Name mangling
class Foo {
func bar() -> Bool {
return false
}
}
_TFC9test3Foo3barfS0_FT_Sb
Compiler features
• Profile-guided optimization (‘off’ by default)
• Loop vectorisation (‘on’ by default from Xcode 6)
• High-level language-specific optimizer and IR
before LLVM (‘xcrun swift t.swift -O -emit-sil')
Performance
• 10-100 x slower than C++ (-O0)
• 10 x slower than C++ (-O3)
• 1 x as C++ (-Ofast)*
Performance
• Swift is still in beta
• Unoptimized calls of retain/release in loops
Pattern matching
let point = (0, 1)
if point.0 == 0 && point.1 == 0 {
println("Point is at the origin")
} else if point.0 >= 0 && point.0 <= 1 &&
point.1 >= 0 && point.1 <= 1 {
println("I")
}
...
Pattern matching let point = (0, 1)
switch point {
case (0, 0):
println("Point is at the origin")
case (0...1, 0...1):
println("I")
case (-1...0, 0...1):
println("II")
case (-1...0, -1...0):
println("III")
case(0...1, -1...0):
println("IV")
default:
println(“I don’t know.")
}
Function currying
func add(a: Int)(b: Int) -> Int {
return a + b
}
let foo = add(5)(b: 3) // 8
let add5 = add(5) // (Int) -> Int
let bar = add5(b: 3) // 8
Auto closures
• Wraps function argument in explicit closure
func assert(condition:() -> Bool, message: String) {
#if DEBUG
if !condition() { println(message) }
#endif
}
assert({5 % 2 == 0}, "5 isn't an even number.")
Cross-platform code
#if os(iOS)
typealias View = UView
#else
typealias View = NSView
#endif
class MyControl : View {
}
Auto closures Wraps function argument in explicit closure
func assert(condition: @auto_closure () -> Bool,
message: String) {
#if DEBUG
if !condition() { println(message) }
#endif
}
assert(5 % 2 == 0, "5 isn't an even number.")
Implicit type conversion
struct Box<T> {
let _value : T
init (_ value: T) {
_value = value
}
}
let value = Box(1)
value + 3 //error
Implicit type conversion
extension Box {
@conversion func __conversion() -> T {
return value
}
}
let value = Box(3 + 3)
value + 3 //9
Implicit type conversion
• allows any type to be ‘nil’ (which has NilType)
• allows toll-free-bridging with Cocoa types
Reflection
struct Foo {
var str = "Apple"
let int = 13
func foo() { }
}
reflect(Foo()).count // 2
reflect(Foo())[0].0 // "str"
reflect(Foo())[0].1.summary // "Apple
Direct call of C functions
@asmname - attribute that allows to provide a Swift interface for C functions
@asmname("my_c_func")
func my_c_func(UInt64, CMutablePointer<UInt64>) -> CInt;
Scripting and REPL
• xcrun swift - launches REPL
• xcrun -i ‘file.swift’ - executes script
Where can I swift?
• BDD Testing framework: Quick
• Reactive programming: RXSwift
• Model mapping: Crust
• Handy JSON processing: SwiftyJSON
Thx!
@delebedev
Credits
• http://nondot.org/sabre/
• https://devforums.apple.com/thread/227288
• http://andelf.github.io/blog/2014/06/08/swift-implicit-type-cast/
• https://www.youtube.com/watch?v=Ii-02vhsdVk
• http://www.eswick.com/2014/06/inside-swift/
• http://article.gmane.org/gmane.comp.compilers.clang.devel/37217
• http://stackoverflow.com/questions/24101718/swift-performance-sorting-arrays
• http://www.splasmata.com/?p=2798
• https://github.com/rodionovd/SWRoute/wiki/Function-hooking-in-Swiftкак