Slide 1

Slide 1 text

ASSERTION OR; HOW I LEARNED TO STOP WORRYING AND LOVE THE APP CRASH SWIFTѪ޷ձ VOL.18 N. HAMADA

Slide 2

Slide 2 text

ࣗݾ঺հ ໊લ: ͸·ͩ iOSྺ: 1೥൒͘Β͍ʹͳΓ·ͨ͠ Mac࣌୅ͱ͔΋͋Γ·ͨ͠ ੲ͸ɺHWͱ͔࡞ͬͯͨΓ Qiita http://qiita.com/HaNoHito GitHub https://github.com/nhamada

Slide 3

Slide 3 text

Agenda ʢ։ൃத͸ʣؾܰʹΫϥογϡͤ͞Α͏

Slide 4

Slide 4 text

How to Crash an App var instance: String! = nil instance.appending("Message")

Slide 5

Slide 5 text

How to Crash an App var instance: String! = nil instance.appending("Message") This is not his story.

Slide 6

Slide 6 text

How to Crash an App struct Animal { let name: String let age: Int } func isAdult(animal: Animal) -> Bool { assert(animal.age >= 0, "Age must be a positive number.") return animal.age >= 20 }

Slide 7

Slide 7 text

How to Crash an App struct Animal { let name: String let age: Int } func isAdult(animal: Animal) -> Bool { assert(animal.age >= 0, "Age must be a positive number.") return animal.age >= 20 } Assertion

Slide 8

Slide 8 text

Assertion લఏ৚݅ ਅͱͳΔ΂͖৚݅ ද໌ِ͕Ͱ͋Δˠόά Swift assert / assertFailure precondition / preconditionFailure

Slide 9

Slide 9 text

Example: assert struct Animal { let name: String let age: Int } func isAdult(animal: Animal) -> Bool { assert(animal.age >= 0, "Age must be a positive number.") return animal.age >= 20 }

Slide 10

Slide 10 text

Example: assert struct Animal { let name: String let age: Int } func isAdult(animal: Animal) -> Bool { assert(animal.age >= 0, "Age must be a positive number.") return animal.age >= 20 } animal.age͸೥ྸΛද͍ͯ͠ΔͷͰ ਖ਼ͷ੔਺Ͱͳ͚Ε͹͍͚ͳ͍

Slide 11

Slide 11 text

assert and precondition

Slide 12

Slide 12 text

assert C෩ͷΞαʔτ conditionِ͕Ͱ͋Ε͹ɺmessageͷ಺༰Λදࣔ͢ Δ condition͕ৗʹِ => assertFailure() func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)

Slide 13

Slide 13 text

precondition લఏ৚݅ͷνΣοΫΛߦ͏ conditionِ͕Ͱ͋Ε͹ɺmessageͷ಺༰Λදࣔ͢ Δ condition͕ৗʹِ => preconditionFailure() func precondition(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)

Slide 14

Slide 14 text

Difference: assert and precondition ࠷దԽϨϕϧʹΑͬͯಈ࡞͕ҟͳΔ Optimization assert precondition -Onone condition͕falseͰ͋Ε͹ ࣮ߦ͕ఀࢭ͞Ε σόοάঢ়ଶʹͳΔ condition͕falseͰ͋Ε͹ ࣮ߦ͕ఀࢭ͞Ε σόοάঢ়ଶʹͳΔ -O condition͸ධՁ͞Εͳ͍ ʢӨڹͳ͠) condition͕falseͰ͋Ε͹ ࣮ߦ͕ఀࢭ -Ounchecked condition͸ৗʹtrueͱ ૝ఆ condition͸ৗʹtrueͱ ૝ఆ

Slide 15

Slide 15 text

Difference: assert and precondition ࠷దԽϨϕϧʹΑͬͯಈ࡞͕ҟͳΔ Optimization assert precondition -Onone condition͕falseͰ͋Ε͹ ࣮ߦ͕ఀࢭ͞Ε σόοάঢ়ଶʹͳΔ condition͕falseͰ͋Ε͹ ࣮ߦ͕ఀࢭ͞Ε σόοάঢ়ଶʹͳΔ -O condition͸ධՁ͞Εͳ͍ ʢӨڹͳ͠) condition͕falseͰ͋Ε͹ ࣮ߦ͕ఀࢭ -Ounchecked condition͸ৗʹtrueͱ ૝ఆ condition͸ৗʹtrueͱ ૝ఆ Debugߏ੒ (Default) Releaseߏ੒ (Default)

Slide 16

Slide 16 text

assert vs precondition Ͳ͏͍͏࢖͍෼͚͕ྑ͍ʁ Usage assert ϩδοΫʹର͢ΔαχςΟνΣοΫ ϝιου಺ͰԿ͔ͷॲཧΛͨ͠ޙͷνΣοΫ precondition ϩδοΫ࣮ߦલͷࣄલ৚݅ͷνΣοΫ ϝιουʹ౉͞ΕͨύϥϝʔλʔͷνΣοΫ ݸਓతʹɺ্هͷΑ͏ͳ࢖͍෼͚ͯ͠·͢ɻ

Slide 17

Slide 17 text

Example ϩάΠϯը໘ ཁ݅ Ϣʔβʔͷঢ়ଶ ະϩάΠϯ ϩάΠϯࡁΈ ಛݖϢʔβʔ ϩάΠϯͰ͖Δͷ͸ɺະϩάΠϯͷͱ͖ ϩάΠϯը໘͔Β͸ಛݖϢʔβʔʹͳΕͳ ͍

Slide 18

Slide 18 text

Example enum UserState { case none case authenticated case superUser } func login(userName: String, password: String) { precondition(!userName.isEmpty, "User name must be non-empty string.") precondition(!password.isEmpty, "Password must be non-empty string.") precondition(state == .none, "App state must be non-login state.") // ϩάΠϯॲཧ assert(state != .superUser, "Cannot become super-user immediately.") }

Slide 19

Slide 19 text

Example enum UserState { case none case authenticated case superUser } func login(userName: String, password: String) { precondition(!userName.isEmpty, "User name must be non-empty string.") precondition(!password.isEmpty, "Password must be non-empty string.") precondition(state == .none, "App state must be non-login state.") // ϩάΠϯॲཧ assert(state != .superUser, "Cannot become super-user immediately.") } લఏ৚݅ Ϣʔβʔ໊ɾύεϫʔυ͸ඞਢ ঢ়ଶ͸ະϩάΠϯͰͳ͚Ε͹͍͚ͳ͍

Slide 20

Slide 20 text

Example enum UserState { case none case authenticated case superUser } func login(userName: String, password: String) { precondition(!userName.isEmpty, "User name must be non-empty string.") precondition(!password.isEmpty, "Password must be non-empty string.") precondition(state == .none, "App state must be non-login state.") // ϩάΠϯॲཧ assert(state != .superUser, "Cannot become super-user immediately.") } ࣄޙ৚݅ ϩάΠϯޙɺ͙͢ʹಛݖϢʔβʔʹ͸ͳΕͳ͍

Slide 21

Slide 21 text

Pros and Cons Pros ໰୊ՕॴΛૣظʹɺଈ࠲ʹಛఆͰ͖Δ σόοά͕ϥΫʹͳΔ ίʔυ্ʹઃܭ࣌ͷ൑அΛ࢒ͤΔ Cons ίʔυॻ͘ྔ͕૿͑Δ ঢ়گʹΑͬͯ͸ɺͻΒ͢ΒΫϥογϡͯ͠ʢQAςετதʣπϥΠ ޻ظ͕ݫ͍͠৔߹ɺͳͲɺπϥϛ͔͠ͳ͍

Slide 22

Slide 22 text

Summary assert/preconditionΛ͏·͘࢖͍ͬͯ͜͏ σόοάͰָ͕Ͱ͖ΔΑ͏ʹ ઃܭ্ͷ൑அΛίʔυʹ࢒͢