Mera Dev Fest - Swift vs. Obj-C
-
Upload
sergey-pronin -
Category
Education
-
view
361 -
download
1
description
Transcript of Mera Dev Fest - Swift vs. Obj-C
Swiftвторое рождение
Objective-C?
Сергей Пронин Empatika НИУ-ВШЭ
Сергей Пронин
Full-stack Developer Empatika
Senior Developer, Co-Founder App in the Air
ПреподавательНИУ-ВШЭ Департамент Программной Инженерии
WWDC 2014
Первые мысли
• WAT?
• У меня были планы на лето
• Пора качать Xcode Beta
• Первый Playground
Apple Good to great
Почему Swift сменит Objective-C
Новый hardware
Watch
WatchKit
Почему Swift?
Почему Swift?• Возможность вернуть несколько значений из метода
Почему Swift?• Возможность вернуть несколько значений из метода
• Optionals
Почему Swift?• Возможность вернуть несколько значений из метода
• Optionals
• Защита от ошибок
Почему Swift?• Возможность вернуть несколько значений из метода
• Optionals
• Защита от ошибок
• Playgrounds
Почему Swift?• Возможность вернуть несколько значений из метода
• Optionals
• Защита от ошибок
• Playgrounds
• Полнофункциональные Enum
Почему Swift?• Возможность вернуть несколько значений из метода
• Optionals
• Защита от ошибок
• Playgrounds
• Полнофункциональные Enum
• “Сладкий” синтаксис
Защита от глупостей
let lang = "swift"
let lang = "swift"switch (lang) {
let lang = "swift"switch (lang) { case "swift":
let lang = "swift"switch (lang) { case "swift": println("young")
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"):
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?")
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css":
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web")
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default:
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}
//<break> чтобы прервать
let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}
//<break> чтобы прервать//<fallthrough> чтобы “провалиться”
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt {
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) {
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) {
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) { //…
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) { //…}
var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
if let langs = langsOpt { println("langs=\(langs)")}
NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) { //…}
Инструменты языка• Отсутствие try-catch конструкций
• Все методы в протоколах - обязательные
• Наличие ключевого слова required
• Модификаторы доступа
• Обязательная инициализация динамических переменных в конструкторе
“Сладкий” синтаксис
enum Status: Int {
enum Status: Int { case Undetermined, Success, Failure
enum Status: Int { case Undetermined, Success, Failure}
enum Status: Int { case Undetermined, Success, Failure}
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status {
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result {
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success:
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success")
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure:
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure")
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined:
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")}
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")}result = Status.fromRaw(1)! //Success
enum Status: Int { case Undetermined, Success, Failure}
func sendRequest() -> Status { //networking magic return Status.Success}
var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")}result = Status.fromRaw(1)! //Successresult.toRaw() //1
func isEven(n: Int) -> Bool {
func isEven(n: Int) -> Bool { return n % 2 == 0
func isEven(n: Int) -> Bool { return n % 2 == 0}
func isEven(n: Int) -> Bool { return n % 2 == 0}
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool)
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] {
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = []
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a {
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) {
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n)
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) }
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } }
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result}
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result}
func isEven(n: Int) -> Bool { return n % 2 == 0}
func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result}
filter(0...10, isEven)
filter(0..<10, { (item: Int) -> Bool in
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0...100, { item in item % 10 == 0 })
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0...100, { item in item % 10 == 0 })
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0...100, { item in item % 10 == 0 })
filter(0...100, { $0 % 10 == 0 })
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0...100, { item in item % 10 == 0 })
filter(0...100, { $0 % 10 == 0 })
filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})
filter(0...100, { item in item % 10 == 0 })
filter(0...100, { $0 % 10 == 0 })
filter(0...100) { $0 % 10 == 0 }
var globalLazy: String = {
var globalLazy: String = { return "Hello, lazy boy"
var globalLazy: String = { return "Hello, lazy boy"}()
var globalLazy: String = { return "Hello, lazy boy"}()
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)")
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults()
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set {
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”)
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize()
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize() }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize() } }
var globalLazy: String = { return "Hello, lazy boy"}()
class Sample { lazy var x: Int = CallMethod()
var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }
let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize() } }}
func + (left: Vector2D, right: Vector2D) -> Vector2D {
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) {
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}func ** (left: Double, right: Double) -> Double {
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}
5 ** 2 // 25.0
func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}
func += (inout left: Vector2D, right: Vector2D) { left = left + right}
let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}
vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}
infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}
5 ** 2 // 25.013 ** 2 // 169.0
Перечисления Enum
“Ассоциированные” значения
• Каждый объект перечисления может содержать объект другого типа в качестве соответствия
• В таком случае их типы могут быть разными
• Позволяет “ассоциировать” любую информацию
enum Barcode { case UPCA(Int, Int, Int) case PDF417(String) }
var productBarcode = Barcode.UPCA(1, 2, 3) productBarcode = .PDF417("ABCD")
Ассоциированные значения доступны в switch-case конструкции
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check):
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code):
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugar
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check):
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code):
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code): println("PDF417 with value of \(code).")
Ассоциированные значения доступны в switch-case конструкции
switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}
// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code): println("PDF417 with value of \(code).")}
“Замещающие” значения
• Каждый объект перечисления может быть сопоставлен с объектом другого типа
• “Замещающие” значения не меняются (в отличие от “ассоциированных”
• Допустимые типы: Character, String, Double, Float, Int*
// для Int работает auto-increment enum Number: Int { case One = 1, Two, Three, Four, Five, Six, Seven, Eight, FortyTwo = 42 }
enum APIMethod: String { case GET = "GET" case POST = "POST" case DELETE = "DELETE" case PUT = "PUT" case HEAD = "HEAD" } func request(method: APIMethod) { var req = NSMutableURLRequest() req.HTTPMethod = method.toRaw() //... }
Скорость?
Objective-C + Swift
Готовимся
typedef enum { StatusSuccess, StatusFailure } Status
typedef NS_ENUM(NSInteger, Status) { StatusSuccess, StatusFailure };
+ (id)sharedInstance { //your singleton magic }
+ (instancetype)sharedInstance { //singleton magic }
- (instancetype)init { //initial magic }
• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header
• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header
• В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C#import “MyAFAPIClient.h”
• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header
• В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C#import “MyAFAPIClient.h”
• Чтобы Obj-C видел из Swift импортируем#import “ProductModuleName-Swift.h”
• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header
• В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C#import “MyAFAPIClient.h”
• Чтобы Obj-C видел из Swift импортируем#import “ProductModuleName-Swift.h”
• Открыть Swift-классы и протоколы через @objc@objc(Venue)class Venue {…}
Конвенции//Person.h @interface Person @property (nonatomic, strong) NSString *name; + (instancetype)personWithName:(NSString *)name; + (instancetype)person; @end
//MyApp-Bridging-Header.h #import "Person.h"
//Main.swift class Main { var person1: Person var person2: Person init() { person1 = Person(name: "Sergey") person2 = Person() } }
Недоступны из Swift в Obj-C
• Swift enum
• Вложенные классы
• Перегруженные операторы
• Swift Extensions (Categories)
• Функции (вне классов)
Недоступны из Obj-C в Swift
• Objective-C++ (.mm)
• typedef enum -> только NS_ENUM
• id -> AnyObject?
Школа
4 занятия20 участников
Скринкасты на YouTube Презентации на SlideShare
Резюме
• Защита от ошибок
• Защита от ошибок
• Модификаторы доступ
• Защита от ошибок
• Модификаторы доступ
• Optionals
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Никаких try-catch - “умный” код
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Никаких try-catch - “умный” код
• Обаятельная инициализация
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Никаких try-catch - “умный” код
• Обаятельная инициализация
• Playgrounds
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Никаких try-catch - “умный” код
• Обаятельная инициализация
• Playgrounds
• “Сладкий” синтаксис
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Никаких try-catch - “умный” код
• Обаятельная инициализация
• Playgrounds
• “Сладкий” синтаксис
• Перегрузка операторов
• Защита от ошибок
• Модификаторы доступ
• Optionals
• “Обновлённый“ switch-case
• Никаких try-catch - “умный” код
• Обаятельная инициализация
• Playgrounds
• “Сладкий” синтаксис
• Перегрузка операторов
• Совместимость Obj-C <-> Swift
https://www.appintheair.mobi/download