KEMBAR78
From android/ java to swift (2) | PDF
From Android/Java to Swift (2)
Allan Shih
Agenda
● Data structures in Swift
● Property
● Method
● Inheritance
● Initialization
● Deinitialization
● Reference
Data Structures in Swift
● class, struct and enum
● Similarities
○ Declaration syntax
○ Properties and Functions
○ Initializers
○ Conform to protocols
● Differences
○ Inheritance (class only)
○ Introspection and casting (class only)
○ Value type (struct, enum) vs. Reference type (class)
class
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print("The frameRate property of tenEighty is now (tenEighty.frameRate)")
// Prints "The frameRate property of tenEighty is now 30.0"
struct
struct Resolution {
var width = 0
var height = 0
}
// Memberwise Initializers for Structure Types
let vga = Resolution(width: 640, height: 480)
var cinema = vga
cinema.width = 2048
print("cinema is now (cinema.width) pixels wide")
// Prints "cinema is now 2048 pixels wide"
print("vga is still (vga.width) pixels wide")
// Prints "vga is still 640 pixels wide"
enum
enum CompassPoint {
case north
case south
case east
case west
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection = .east
if rememberedDirection == .west {
print("The remembered direction is still .west")
}
// Prints "The remembered direction is still .west"
Associated Values
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: (numberSystem), (manufacturer), (product), (check).")
case .qrCode(let productCode):
print("QR code: (productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
Implicitly Assigned Raw Values
enum StatusCode: Int {
case success = 0
case internalServerError = 103
case apikeyInvalid = 104
case apiKeyMissing = 108
case apiKeyNotAuthorized = 118
case filterKeyInvalid = 333
case filterGroupMissingForLanguage = 334
case invalidBucketKey = 337
public static func isSuccess(status: Int) -> Bool {
return success.rawValue == status
}
}
print(StatusCode.apikeyInvalid.rawValue)
var code = 0
print(StatusCode.isSuccess(status: code))
Lazy Stored Properties
class DataImporter {
var fileName = "data.txt"
// the DataImporter class would provide data importing functionality here
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
// the DataManager class would provide data management functionality here
}
let manager = DataManager()
manager.data.append("Some data")
print(manager.importer.fileName)
// the DataImporter instance for the importer property has now been created
Computed Properties
struct AlternativeRect {
var origin = Point() // Stored Properties
var size = Size()
var center: Point { // Computed Properties
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
Property Observers
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to (newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added (totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
Modifying Value Types from Within Instance Methods
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at ((somePoint.x), (somePoint.y))")
// Prints "The point is now at (3.0, 4.0)"
Inheritance
class Vehicle {
var description: String {
return "traveling at (currentSpeed) miles per hour"
}
func makeNoise() {
// do nothing - an arbitrary vehicle doesn't necessarily make a noise
}
}
class Train: Vehicle {
override func makeNoise() {
print("Override method")
}
}
class Car: Vehicle {
override var description: String {
return super.description + " Override property in gear (gear)"
}
}
Initialization Parameters
struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
// boilingPointOfWater.temperatureInCelsius is 100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
// freezingPointOfWater.temperatureInCelsius is 0.0
Syntax for Designated and Convenience Initializers
● Designated initializers are the primary initializers for a class.
init(parameters) {
statements
}
● Convenience initializers are secondary, supporting initializers for a class.
convenience init(parameters) {
statements
}
Initializer Delegation for Class Types
● Rule 1
A designated initializer must call a designated initializer from its
immediate superclass.
● Rule 2
A convenience initializer must call another initializer from the same class.
● Rule 3
A convenience initializer must ultimately call a designated initializer.
Initializer Delegation for Class Types
Designated and Convenience Initializers in Action
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int) {
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String) {
self.init(name: name, quantity: 1)
}
}
Designated and Convenience Initializers in Action
Deinitialization
class Player {
var coinsInPurse: Int
init(coins: Int) {
coinsInPurse = Bank.distribute(coins: coins)
}
func win(coins: Int) {
coinsInPurse += Bank.distribute(coins: coins)
}
deinit {
Bank.receive(coins: coinsInPurse)
}
}
Reference
● The Swift Programming Language (Swift 3.0.1)
● Completion Handlers in Swift
● 从Java/Android到Swift iOS开发

From android/ java to swift (2)

  • 1.
    From Android/Java toSwift (2) Allan Shih
  • 2.
    Agenda ● Data structuresin Swift ● Property ● Method ● Inheritance ● Initialization ● Deinitialization ● Reference
  • 3.
    Data Structures inSwift ● class, struct and enum ● Similarities ○ Declaration syntax ○ Properties and Functions ○ Initializers ○ Conform to protocols ● Differences ○ Inheritance (class only) ○ Introspection and casting (class only) ○ Value type (struct, enum) vs. Reference type (class)
  • 4.
    class class VideoMode { varresolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? } let tenEighty = VideoMode() tenEighty.resolution = hd tenEighty.interlaced = true tenEighty.name = "1080i" tenEighty.frameRate = 25.0 let alsoTenEighty = tenEighty alsoTenEighty.frameRate = 30.0 print("The frameRate property of tenEighty is now (tenEighty.frameRate)") // Prints "The frameRate property of tenEighty is now 30.0"
  • 5.
    struct struct Resolution { varwidth = 0 var height = 0 } // Memberwise Initializers for Structure Types let vga = Resolution(width: 640, height: 480) var cinema = vga cinema.width = 2048 print("cinema is now (cinema.width) pixels wide") // Prints "cinema is now 2048 pixels wide" print("vga is still (vga.width) pixels wide") // Prints "vga is still 640 pixels wide"
  • 6.
    enum enum CompassPoint { casenorth case south case east case west } var currentDirection = CompassPoint.west let rememberedDirection = currentDirection currentDirection = .east if rememberedDirection == .west { print("The remembered direction is still .west") } // Prints "The remembered direction is still .west"
  • 7.
    Associated Values enum Barcode{ case upc(Int, Int, Int, Int) case qrCode(String) } var productBarcode = Barcode.upc(8, 85909, 51226, 3) productBarcode = .qrCode("ABCDEFGHIJKLMNOP") switch productBarcode { case .upc(let numberSystem, let manufacturer, let product, let check): print("UPC: (numberSystem), (manufacturer), (product), (check).") case .qrCode(let productCode): print("QR code: (productCode).") } // Prints "QR code: ABCDEFGHIJKLMNOP."
  • 8.
    Implicitly Assigned RawValues enum StatusCode: Int { case success = 0 case internalServerError = 103 case apikeyInvalid = 104 case apiKeyMissing = 108 case apiKeyNotAuthorized = 118 case filterKeyInvalid = 333 case filterGroupMissingForLanguage = 334 case invalidBucketKey = 337 public static func isSuccess(status: Int) -> Bool { return success.rawValue == status } } print(StatusCode.apikeyInvalid.rawValue) var code = 0 print(StatusCode.isSuccess(status: code))
  • 9.
    Lazy Stored Properties classDataImporter { var fileName = "data.txt" // the DataImporter class would provide data importing functionality here } class DataManager { lazy var importer = DataImporter() var data = [String]() // the DataManager class would provide data management functionality here } let manager = DataManager() manager.data.append("Some data") print(manager.importer.fileName) // the DataImporter instance for the importer property has now been created
  • 10.
    Computed Properties struct AlternativeRect{ var origin = Point() // Stored Properties var size = Size() var center: Point { // Computed Properties get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set { origin.x = newValue.x - (size.width / 2) origin.y = newValue.y - (size.height / 2) } } }
  • 11.
    Property Observers class StepCounter{ var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to (newTotalSteps)") } didSet { if totalSteps > oldValue { print("Added (totalSteps - oldValue) steps") } } } } let stepCounter = StepCounter() stepCounter.totalSteps = 200 // About to set totalSteps to 200 // Added 200 steps stepCounter.totalSteps = 360 // About to set totalSteps to 360 // Added 160 steps
  • 12.
    Modifying Value Typesfrom Within Instance Methods struct Point { var x = 0.0, y = 0.0 mutating func moveBy(x deltaX: Double, y deltaY: Double) { x += deltaX y += deltaY } } var somePoint = Point(x: 1.0, y: 1.0) somePoint.moveBy(x: 2.0, y: 3.0) print("The point is now at ((somePoint.x), (somePoint.y))") // Prints "The point is now at (3.0, 4.0)"
  • 13.
    Inheritance class Vehicle { vardescription: String { return "traveling at (currentSpeed) miles per hour" } func makeNoise() { // do nothing - an arbitrary vehicle doesn't necessarily make a noise } } class Train: Vehicle { override func makeNoise() { print("Override method") } } class Car: Vehicle { override var description: String { return super.description + " Override property in gear (gear)" } }
  • 14.
    Initialization Parameters struct Celsius{ var temperatureInCelsius: Double init(fromFahrenheit fahrenheit: Double) { temperatureInCelsius = (fahrenheit - 32.0) / 1.8 } init(fromKelvin kelvin: Double) { temperatureInCelsius = kelvin - 273.15 } } let boilingPointOfWater = Celsius(fromFahrenheit: 212.0) // boilingPointOfWater.temperatureInCelsius is 100.0 let freezingPointOfWater = Celsius(fromKelvin: 273.15) // freezingPointOfWater.temperatureInCelsius is 0.0
  • 15.
    Syntax for Designatedand Convenience Initializers ● Designated initializers are the primary initializers for a class. init(parameters) { statements } ● Convenience initializers are secondary, supporting initializers for a class. convenience init(parameters) { statements }
  • 16.
    Initializer Delegation forClass Types ● Rule 1 A designated initializer must call a designated initializer from its immediate superclass. ● Rule 2 A convenience initializer must call another initializer from the same class. ● Rule 3 A convenience initializer must ultimately call a designated initializer.
  • 17.
  • 18.
    Designated and ConvenienceInitializers in Action class Food { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[Unnamed]") } } class RecipeIngredient: Food { var quantity: Int init(name: String, quantity: Int) { self.quantity = quantity super.init(name: name) } override convenience init(name: String) { self.init(name: name, quantity: 1) } }
  • 19.
    Designated and ConvenienceInitializers in Action
  • 20.
    Deinitialization class Player { varcoinsInPurse: Int init(coins: Int) { coinsInPurse = Bank.distribute(coins: coins) } func win(coins: Int) { coinsInPurse += Bank.distribute(coins: coins) } deinit { Bank.receive(coins: coinsInPurse) } }
  • 21.
    Reference ● The SwiftProgramming Language (Swift 3.0.1) ● Completion Handlers in Swift ● 从Java/Android到Swift iOS开发