| 
        
       | 
      
        import Foundation
class Example {
    var a = 0
    var b: String
    init(a: Int) { // Constructor
        self.a = a
        b = "name"                  // An error if a declared property isn't initialized
    }
}
 
       | 
    
    
      | 
         External param names are required...
       | 
      
        let eg = Example(a: 1)
print(eg.a)              // 1
 
       | 
    
    
      | 
         ...Unless the params are declared with leading underscores.
       | 
      
        
class Example2 {
    var a = 0
    var b = 0
    init(_ a: Int, _ b: Int) {
        self.a = a
        self.b = b
    }
}
let eg2 = Example2(1, 2)
print(eg2.a)            // 1
print(eg2.b)            // 2
 
       | 
    
    
      
         # Lazy properties
       | 
      
          
       | 
    
    
      | 
         Lazy properties' initial value aren't
       | 
      
          
       | 
    
    
      | 
         initialized until the first time the
       | 
      
          
       | 
    
    
      | 
         property is accessed.
       | 
      
        
class Podcast {
    lazy var episode = Episode() // `var` declaration is required.
}
class Episode {
    var audio = "somefile.mp3"
}
var podcast = Podcast()          // episode has not been initialized yet.
print(podcast.episode.audio)   // somefile.mp3
 
       | 
    
    
      
         # Computed properties
       | 
      
          
       | 
    
    
      | 
         Computed properties don't store a value. Instead, getters / setters
       | 
      
          
       | 
    
    
      | 
         are provided to retrieve and set _other_ properties.
       | 
      
        
class Window {
    var x = 0.0, y = 0.0
    var width = 100.0, height = 100.0
    var center: (Double, Double) {
        get {
            return (width / 2, height / 2)
        }
        set(newVal) {
            x = newVal.0 - (width / 2)
            y = newVal.1 - (height / 2)
        }
    }
}
var win = Window()
print(win.center)               // (50.0, 50.0)
win.center = (0.0, 10.0)
print(win.x)                    // -50.0
print(win.y)                    // -40.0
 
       | 
    
    
      
         The param to set can be omitted and a magic "newValue"
       | 
      
          
       | 
    
    
      | 
         can be used to referenced the new value.
       | 
      
        /*
set {
x = newValue.0 - (width / 2)
}
*/
 
       | 
    
    
      
         # Read-only computed properties
       | 
      
        
class Song {
    var title = ""
    var duration = 0.0
    var metaInfo: [String:String] {
        return [
            "title": self.title,
            "duration": NSString(format: "%.2f", self.duration) as String,
        ]
    }
}
var song = Song()
song.title = "Rootshine Revival"
song.duration = 2.01
print(song.metaInfo["title"]!)    // Rootshine Revival
print(song.metaInfo["duration"]!) // 2.01
 
       | 
    
    
      
         # Property Observers
       | 
      
          
       | 
    
    
      | 
         Property observers can be added onto any properties
       | 
      
          
       | 
    
    
      | 
         (including inherited) except for lazy computed props.
       | 
      
        
class Website {
    var visitors: Int = 0 {             // An explicit type is required
        willSet(newVisitorCount) {          // Called before the prop is set
            visitors = newVisitorCount + 1  // Warning. Can't set within its own willSet
        }
        didSet {                            // Called after a new val is set
            print(visitors - oldValue)    // oldValue is magically defined
        }
    }
}
var site = Website()
site.visitors = 1
print(site.visitors)                 // 1
 
       | 
    
    
      
         # Type Properties
       | 
      
          
       | 
    
    
      | 
         AKA class variables
       | 
      
        class Body {
    /*    class var age = 0                 // error: class variables not yet supported */
    // Computed type property
    class var size: Int {
        return 10
    }
}
print(Body.size)                     // 10
 
       | 
    
    
      
         # Type Methods
       | 
      
          
       | 
    
    
      | 
         AKA class methods
       | 
      
        class Banana {
    var color = "green"
    class func genus() -> String {
        return "Musa"
    }
}
print(Banana.genus())                // Musa
 
       | 
    
    
      
         # Instance methods
       | 
      
        
class Month {
    var name: String
    init(name: String) {
        self.name = name
    }
    func shortened() -> String {
        return name[name.startIndex..<advance(name.startIndex, 3)]
    }
}
print(Month(name: "January").shortened())    // Jan
 
       | 
    
    
      
         # Inheritance
       | 
      
          
       | 
    
    
      | 
         Swift classes do not inherit from a universal base class.
       | 
      
        
class Bicycle {
    var tireWidth: Double
    var topSpeed: Double
    var name: String
    var gears: Int
    // Marking a method/property with `@final` prevents it from being overridden
    final var color = "green"
    init() {
        tireWidth = 30.5
        topSpeed = 10.0
        name = "regular ol' bike"
        gears = 3
    }
    func go(distance: Double) {
        print("Went \(distance) at a top speed of \(topSpeed) in my \(name)")
    }
}
class MountainBike : Bicycle {
    /* var tireWidth = 64.0 // Cannot override property in the declaration */
    override init() {
        super.init()
        tireWidth = 64.0
        name = "mountain bike"
        gears = 12
    }
    // Override parent's methods via `override` keyword
    override func go(distance: Double) {
        super.go(distance)
        print("Did \(distance) on a mountain bike")
    }
    // A getter/setter override can _any_ inherited property.
    override var topSpeed: Double {
        get {
            return super.topSpeed - 4.0
        }
        set {
            super.topSpeed = newValue
        }
    }
    // Property observer
    override var gears: Int {
        didSet {
            print("Gears was changed to \(gears)")
        }
    }
}
var mountainBike = MountainBike()              // Gears was changed to 12
mountainBike.topSpeed = 6.0
print(mountainBike.topSpeed)                 // 2.0
mountainBike.go(12.0)                          // Went 12.0 at a top speed of 10.0 in my mountain bike
 
       | 
    
    
      | 
         Did 12.0 on a mountain bike
       | 
      
          
       | 
    
    
      
         # Initializers
       | 
      
          
       | 
    
    
      | 
         'Convenience' initializers overload empty
       | 
      
          
       | 
    
    
      | 
         initializers that populate the params
       | 
      
          
       | 
    
    
      | 
         in 'designated' initializers.
       | 
      
        
class iOS {
    var version: String
    init(version: String) {
        self.version = version
    }
    convenience init() {
        self.init(version: "8.0.0")
    }
}
var os = iOS()
print(os.version)                          // 8.0.0
 
       | 
    
    
      
         # ARC and reference cycles
       | 
      
          
       | 
    
    
      | 
         Strong reference cycles happen when two objects
       | 
      
          
       | 
    
    
      | 
         hold strong references to each other so that neither
       | 
      
          
       | 
    
    
      | 
         can be deallocated (à la memory leaks in garbage collected langs)
       | 
      
          
       | 
    
    
      | 
         Strong references can be resolved by declaring
       | 
      
          
       | 
    
    
      
         references as weak or unowned
       | 
      
          
       | 
    
    
      | 
         Use a weak reference whenever it's valid for the reference
       | 
      
          
       | 
    
    
      | 
         to be nil at any point. These are optional types.
       | 
      
        
class Driver {
    weak var car: Car? // Strong reference to car.
    deinit {
        print("Driver deinitialized")
    }
}
class Car {
    weak var driver: Driver? // Weak reference to driver.
    deinit {
        print("Car deinitialized")
    }
}
var driver: Driver?
var car: Car?
driver = Driver()
car = Car()
driver!.car = car
car!.driver = driver
driver = nil               // No more strong references to driver.
car = nil                  // No more strong references to car.
 
       | 
    
    
      | 
         Unowned references are like weak references except they always
       | 
      
          
       | 
    
    
      | 
         refer to a value, so they're non-nil.
       | 
      
        
class Artist {
    var instrument: Instrument?  // Strong reference to instrument.
}
class Instrument {
    unowned let artist: Artist   // Unowned reference to artist.
    init (artist: Artist) {
        self.artist = artist
    }
}
var artist: Artist?
artist = Artist()
artist!.instrument = Instrument(artist: artist!)
artist = nil        // Both objects are deallocated since there are no more strong references.
 
       | 
    
    
      
         # Access control
       | 
      
          
       | 
    
    
      | 
         Access control in Swift is very much package-based.
       | 
      
          
       | 
    
    
      
         private: Can only be accessed from the same source file that it's defined
       | 
      
          
       | 
    
    
      
         internal: Can be accessed anywhere in the target it's defined
       | 
      
          
       | 
    
    
      
         public: Accessible anywhere in the target and anywhere its module is imported
       | 
      
          
       | 
    
    
      
         Defaults to internal if not explicitly declared.
       | 
      
        
internal class Image { // Accessible in the same target
    internal var name : String
    private var mime : String {     // Accessible only in this file. Never settable.
        get {
            return "image/\(name.pathExtension)"
        }
    }
    init(name: String) {
        self.name = name
    }
}
var img = Image(name: "foo.png")
public class Webpage {
    public var title : String
    public var created : NSDate
    private(set) var images : [Image] // Readable within the same target but only writable in this file
    var slug : String {
        return created.description + title
    }
    init(title: String) {
        self.title = title
        self.created = NSDate()
        self.images = []
    }
}
var webPage = Webpage(title: "blog post")
webPage.images.append(Image(name:"panda.gif"))
 
       |