Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift

 Swift

Slides from Mobile Optimized 2014

C4edd51fe88b9820a046db724d53fd91?s=128

Denis Lebedev

June 29, 2014
Tweet

Transcript

  1. Swift Denis Lebedev, iOS @ Yandex

  2. Agenda • Introduction • Objective-C bridging • Good-to-know features •

    “Where can I Swift?”
  3. Swift Chris Lattner, Swift creator

  4. Swift • Multi-paradigm • Static, inferred typing • Bridged with

    Objective-C • No pointers
  5. –Someone at WWDC Keynote It’s like “Objective-C without C.”

  6. None
  7. Swift features • Namespacing* • Generic classes & functions •

    Named/default parameters • Functions are first class citizens • Optional types
  8. Optionals • Used in situations where value may be absent

    • Alternative for obj-c nil passing • works with any type
  9. Optionals - (NSInteger)indexOfObject:(id)object;

  10. Optionals func indexOf(object: AnyObject) -> Int?

  11. Optionals • Can be safely unwrapped (if/else) • Can be

    force unwrapped (runtime exception if value is missing)
  12. Classes, structs, enumerations • Classes passed by reference, structs -

    by value • Using a struct has no runtime penalty • All scalars and even Bool are structs • Enumerations are extremely powerful
  13. Enumerations enum Tree { case Empty case Leaf case Node

    }
  14. Enumerations enum Tree { case Empty case Leaf(Int) case Node(Tree,

    Tree) }
  15. Enumerations enum Tree<T> { case Empty case Leaf(T) case Node(Tree,

    Tree) }
  16. Enumerations let tree: Tree<Int> = .Node(.Leaf(1), .Leaf(1))

  17. Enumerations enum Tree<T> { case Empty case Leaf(T) case Node(Tree,

    Tree) ! func depth<T>(t: Tree<T>) -> Int { return 0 } }
  18. Enumerations enum Tree<T> { case … ! func depth() ->

    Int { func _depth<T>(t: Tree<T>) -> Int { return 0 } return _depth(self) } }
  19. Enumerations enum Tree<T> { case … ! func depth() ->

    Int { func _depth<T>(t: Tree<T>) -> Int { switch t { case .Empty: return 0 } return _depth(self) } }
  20. Enumerations enum Tree<T> { case … ! func depth() ->

    Int { func _depth<T>(t: Tree<T>) -> Int { switch t { case .Empty: return 0 case .Leaf(let _): return 1 } return _depth(self) } ! }
  21. Enumerations enum Tree<T> { case … ! func depth() ->

    Int { func _depth<T>(t: Tree<T>) -> Int { switch t { case .Empty: return 0 case .Leaf(let _): return 1 case .Node(let lhs, let rhs): return max(_depth(lhs), _depth(rhs)) } } return _depth(self) } }
  22. Enumerations enum Tree<T> { case Empty case Leaf(T) case Node(Tree,

    Tree) ! func depth() -> Int { func _depth<T>(t: Tree<T>) -> Int { switch t { case .Empty: return 0 case .Leaf(let _): return 1 case .Node(let lhs, let rhs): return max(_depth(lhs), _depth(rhs)) } } return _depth(self) } }
  23. Collections • Array, Dictionary, String (contains Char) • Collections are

    structs • Implicitly bridged to Cocoa collection types
  24. Collections func filter<S : Sequence>(…) -> Bool) -> FilterSequenceView<S> !

    func reverse<C : Collection …>(source: C) -> ReverseView<C> Some of operations are lazy evaluated
  25. Collections func filter<S : Sequence>(…) -> Bool) -> FilterSequenceView<S> !

    func reverse<C : Collection …>(source: C) -> ReverseView<C> Some of operations are lazy evaluated
  26. Built-in immutability var b = 3 b += 1 !

    let a = 3 a += 1 // error
  27. Dictionary immutability let d = ["key0": 0] ! d["key"] =

    3 //error d.updateValue(1, forKey: "key1") //error
  28. Array immutability let c = [1, 2, 3] ! c[0]

    = 3 // success c.append(5) // fail
  29. 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
  30. Extensions • extends any named type (struct, enum, class) •

    structures code
  31. 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 }
  32. What Swift is missing • Preprocessor • Exceptions • Access

    control * • KVO, KVC • Compiler attributes (platforms, deprecations, etc.) • performSelector: is unavailable
  33. 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
  34. Objective-C bridging • NSArray < - > Array • NSDictionary

    < - > Dictionary • NSNumber - > Int, Double, Float
  35. Objective-C bridging @objc class Foo { init (bar: String) {

    /*...*/ } }
  36. Objective-C bridging @objc(objc_Foo) class Foo { ! @objc(initWithBar:) init (bar:

    String) { /*...*/ } ! }
  37. Objective-C bridging Foo *foo = [[Foo alloc] initWithBar:@"Bar"];

  38. Objective-C bridging func convertPoint(point: CGPoint, toWindow window: UIWindow!) -> CGPoint

    - (CGPoint)convertPoint:(CGPoint)point toWindow: (UIWindow *)window
  39. Objective-C bridging • All object types are mapped as implicitly

    unwrapped optionals (T!) • All ‘id’ types are mapped as ‘AnyObject’
  40. Swift internals • Swift objects are Obj-c objects • Implicit

    root class ‘SwiftObject’ • Ivars type encoding is stored separately • Method’s vtable • Name mangling
  41. Name mangling class Foo { func bar() -> Bool {

    return false } } _TFC9test3Foo3barfS0_FT_Sb Swift keeps function metadata encoded in function symbols
  42. Performance • 10-100 x slower than C++ (-O0) • 10

    x slower than C++ (-O3) • 1 x as C++ (-Ofast)*
  43. Performance • Swift is still in beta • Unoptimized calls

    of retain/release in loops
  44. Cross-platform code #if os(iOS) typealias View = UView #else typealias

    View = NSView #endif ! class MyControl : View { }
  45. Pattern matching let point = (0, 1) ! if point.0

    >= 0 && point.0 <= 1 && point.1 >= 0 && point.1 <= 1 { println("I") } ! ...
  46. Pattern matching let point = (0, 1) ! switch point

    { case (0...1, 0...1): println("I") … }
  47. 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.") }
  48. 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
  49. 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.")
  50. 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.")
  51. Implicit type conversion struct Box<T> { let _value : T

    init (_ value: T) { _value = value } } ! let boxedInt = Box(1) //Box<Int>
  52. Implicit type conversion func foo(i: Int) {…} ! foo(boxedInt) //error:

    ’Box<Int>' is not convertible to 'Int'
  53. Implicit type conversion extension Box { @conversion func __conversion() ->

    T { return _value } } ! ! foo(boxedInt) //success
  54. Implicit type conversion • allows any type to be ‘nil’

    (which has NilType) • allows toll-free-bridging with Cocoa types
  55. 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
  56. Direct call of C functions @asmname - allows to provide

    a Swift interface for C functions @asmname("my_c_func") func my_c_func(UInt64, CMutablePointer<UInt64>) -> CInt;
  57. Scripting and REPL • xcrun swift - launches REPL •

    xcrun -i ‘file.swift’ - executes script
  58. Where can I swift? • BDD Testing framework: Quick! •

    Reactive programming: RXSwift • Model mapping: Crust • Handy JSON processing: SwiftyJSON
  59. Thx! @delebedev lebedzeu@yandex-team.ru

  60. 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