Slide 1

Slide 1 text

:VLJ:BTPTIJNB!ZBTP@TBO 4XJGU$PODVSSFODZͱ ϨʔείϯσΟγϣϯ "GUFSJ04%$+BQBO

Slide 2

Slide 2 text

ඇಉظॲཧͰى͖Δ໰୊ w σʔλڝ߹ w ϨʔείϯσΟγϣϯ ؒҧͬͨίʔυΛॻ͍ͯ΋େ఍໰୊ͳ͘ಈ͍ͯ͠·͏

Slide 3

Slide 3 text

4XJGU$PODVSSFODZͰ͸ʁ w 4XJGU$PODVSSFODZ͕ίϯύΠϧ࣌ʹอূ͢Δͷ͸σʔλڝ߹·Ͱ w ϨʔείϯσΟγϣϯͷ໰୊͸ɺ ҎલͱมΘΒ࣮ͣ૷ऀ͕ؾΛ͚ͭΔඞཁ͕͋Δ

Slide 4

Slide 4 text

4XJGU$PODVSSFODZͷ࢓૊Έ w "DUPSSFFOUSBODZʢ"DUPSͷ࠶ೖՄೳੑʣ w $PPQFSBUJWF5ISFBE1PPMʢڠௐతεϨουϓʔϧʣ

Slide 5

Slide 5 text

nonisolated func asyncMethod(_ value: Int) async -> Int { ... } ... Task { @MainActor in let value = makeValue() let result = await asyncMethod(value) print("result : \(result)") } ॲཧ͕ܧଓ࣮ͯ͠ߦ͞ΕΔ୯Ґ ᶃ ᶄ ᶅ ᶃϝΠϯ ᶄ#( ᶅϝΠϯ 4VTQFOUJPO1PJOU εϨου $POUJOVBUJPO ϝΠϯ

Slide 6

Slide 6 text

nonisolated func asyncMethod(_ value: Int) async -> Int { ... } ... Task { @MainActor in let value = makeValue() let result = await asyncMethod(value) print("result : \(result)") } ॲཧ͕ܧଓ࣮ͯ͠ߦ͞ΕΔ୯Ґ ᶃ ᶄ ᶅ ᶃϝΠϯ ᶄ ᶅϝΠϯ 4VTQFOUJPO1PJOU εϨου $POUJOVBUJPO ᶄ ᶄ

Slide 7

Slide 7 text

$PPQFSBUJWF5ISFBE1PPM ڠௐతεϨουϓʔϧ εϨου εϨου ࣮ߦ଴ͪ "DUPSᶃ "DUPSᶄ /PO*TPMBUFE Task { @MainActor in let value = makeValue() let result = await asyncMethod(value) return "fetched : " + result } Task { } 5BTLͷ࣮ߦ

Slide 8

Slide 8 text

nonisolated func method() { ᶃ Task.detached { ᶄ } Task.detached { ᶅ } ᶆ } ࣮ߦ͞ΕΔॱ൪ w ᶄɺᶅɺᶆ͸ฒྻͰ࣮ߦ͞ ΕΔ શͯ/PO*TPMBUFEͷ৔߹ ᶃ ᶆ ᶄ ᶅ εϨου

Slide 9

Slide 9 text

nonisolated func method() { ᶃ Task.detached { ᶄ } Task.detached { ᶅ } ᶆ } ࣮ߦ͞ΕΔॱ൪ w ᶄɺᶅɺᶆ͸ฒྻͰ࣮ߦ͞ ΕΔ w ᶆͷޙʹᶄɺᶅ͕ಉ͡εϨ ουͷՄೳੑ΋ͳ͘͸ͳ͍ શͯ/PO*TPMBUFEͷ৔߹ ᶃ ᶆ ᶄ ᶅ εϨου ᶄ ᶅ

Slide 10

Slide 10 text

@MyActor func method() { ᶃ Task { @MyActor in ᶄ } Task { @MyActor in ᶅ } ᶆ } w ·ͣᶃɺᶆ͕࣮ߦ͞ΕΔ w ᶄɺᶅ͸ ฒྻʹ͸࣮ߦ͞Εͳ͍͕ ͲͪΒ͔Β ࣮ߦ͞ΕΔ͔͸Θ͔Βͳ͍ ࣮ߦ͞ΕΔॱ൪ ಉ͡"DUPSͷ৔߹ εϨου ᶃ ᶆ ᶄ ᶅ ᶄ ᶅ ʁ

Slide 11

Slide 11 text

໰୊ͷ͋ΔίʔυΛվળ͢Δ

Slide 12

Slide 12 text

໰୊ͷ͋Δίʔυྫ λοϓͨ͠਺ͷϩάΛૹΔ w λοϓ͢ΔͨͼʹϩʔΧϧʹอ͍࣋ͯ͠Δ਺Λ૿΍͢ w ఆظతʹ਺Λαʔόʔʹૹ৴͢Δ w ૹ৴ͨ͠ΒϩʔΧϧͷ਺ΛϦηοτ͢Δ

Slide 13

Slide 13 text

໰୊ͷ͋Δίʔυྫ actor Counter { var count: Int = 0 func increment() { count += 1 } func reset() { count = 0 } } class CountLogger { private let counter = Counter() func increment() async { await counter.increment() } // ఆظతʹؒΛ͓͍ͯݺ͹ΕΔ૝ఆ func post() async { let count = await counter.count await postCountLog(count) await counter.reset() } }

Slide 14

Slide 14 text

class CountLogger { func increment() async { ... } ... func post() async { let count = await counter.count await postCountLog(count) await counter.reset() } } w DPVOUऔಘ͔ͯ͠ΒSFTFU͢Δ·ͰͷؒʹJODSFNFOU ͕ݺ͹ΕΔͱ ͦͷ૿Ճ෼͸QPTU͞ΕͣʹSFTFU͞ΕΔ

Slide 15

Slide 15 text

class CountLogger { func increment() async { ... } ... func post() async { let count = await counter.count await counter.reset() await postCountLog(count) } } w DPVOUऔಘޙʹ͙͢SFTFUͯ͠΋ɺ 4VTQFOUJPO1PJOUͰJODSFNFOU͕ݺ͹ΕΔՄೳੑ͕͋Δ

Slide 16

Slide 16 text

actor CountLogger { func increment() async { ... } ... func post() async { let count = await counter.count await counter.reset() await postCountLog(count) } } w BDUPSʹͯ͠΋4VTQFOUJPO1PJOU͕ೖΔ͜ͱ͸มΘΒͳ͍

Slide 17

Slide 17 text

վળͨ͠ίʔυ actor Counter { private var count: Int = 0 func increment() { count += 1 } func pull() -> Int { let count = self.count self.count = 0 return count } } actor CountLogger { private let counter = Counter() func increment() async { await counter.increment() } // ఆظతʹؒΛ͓͍ͯݺ͹ΕΔ૝ఆ func post() async { let count = await counter.pull() await postCountLog(count) } }

Slide 18

Slide 18 text

actor Counter { private var count: Int = 0 ... func pull() -> Int { let count = self.count self.count = 0 return count } } w DPVOUͷऔಘͱϦηοτΛBDUPSͷϝιουͭͰߦ͏͜ͱͰ 4VTQFOUJPO1PJOU͕ೖΔ͜ͱͳ͘ͳΔ

Slide 19

Slide 19 text

αϯϓϧͷ࢓༷มߋ λοϓͨ͠਺ͷϩάΛૹΓ߹ܭΛදࣔ w λοϓ͢ΔͨͼʹϩʔΧϧʹอ͍࣋ͯ͠Δ਺Λ૿΍͢ w ఆظతʹ਺Λαʔόʔʹૹ৴͢Δ w ૹ৴ͨ͠ΒϩʔΧϧͷ਺ΛϦηοτ͢Δ w ૹ৴࣌ʹαʔόʔ͔Β߹ܭΛฦ͠දࣔ͢Δ /FX

Slide 20

Slide 20 text

func post() async -> Int { let count = await counter.pull() let total = await postCountLog(count) return total } w ಉ࣌ʹݺ͹ΕΔͱɺޙ͔ΒݺΜͩํ͕ઌʹऴΘΔՄೳੑ͕͋Δ w BDUPS͕ಉ͡Ͱ΋ؔ܎ͳ͍ func post() async -> Int { let count = await counter.pull() let total = await postCountLog(count) return total } ઌʹݺΜͩॲཧ ޙ͔ΒݺΜͩॲཧ

Slide 21

Slide 21 text

w ݺͼग़͢λΠϛϯά͕ॏෳ͢Δͱ໰୊͕ى͖ΔՄೳੑ͕͋Δ Task { let total = await logger.post() print("total : \(total)") } ͱΓ͋͑ͣ5BTL ❓

Slide 22

Slide 22 text

5JNFSͰ5BTLΛ܁Γฦ࣮͠ߦ w QPTUͷॲཧ͕5JNFSͷJOUFSWBMΛ௒͑Δͱɺ QPTUͷॲཧ͕ॏෳ͢ΔՄೳੑ͕͋Δ Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { _ in Task { let total = await logger.post() print("total : \(total)") } } ❌

Slide 23

Slide 23 text

w 5BTLͷதͰϧʔϓ͢Ε͹ɺQPTUͷॲཧ͸ॏෳ͠ͳ͍ Task { while true { await logger.post() print("total : \(total)") try await Task.sleep(for: .seconds(10)) } } 5BTLͰ܁Γฦ࣮͠ߦ

Slide 24

Slide 24 text

αϯϓϧͷ࢓༷มߋ λοϓͨ͠਺ͷϩάΛૹΓ߹ܭΛදࣔ w λοϓ͢ΔͨͼʹϩʔΧϧʹอ͍࣋ͯ͠Δ਺Λ૿΍͢ w ఆظతʹ਺Λαʔόʔʹૹ৴͢Δ w ૹ৴ͨ͠ΒϩʔΧϧͷ਺ΛϦηοτ͢Δ w ૹ৴࣌ʹαʔόʔ͔Β߹ܭΛฦ͠දࣔ͢Δ w ࣗ༝ͳλΠϛϯάͰ਺Λαʔόʔʹૹ৴͢Δ /FX

Slide 25

Slide 25 text

var isProcessing: Bool = false func post() { Task { guard !isProcessing else { return } isProcessing = true let total = await logger.post() print("total : \(total)”) isProcessing = false } } ˞"DUPS͸ಉ͡૝ఆ ඇಉظॲཧͷॏෳΛεΩοϓ

Slide 26

Slide 26 text

w ௚઀࣮ߦͤͣɺผ5BTLͰඇಉظॲཧ͕௚ྻʹ࣮ߦ͞ΕΔΑ͏ʹ͢Δ w ͨͩ͠ɺݺͼग़͠ଆ͕࣮ࡍͷඇಉظॲཧͷ׬ྃΛ଴ͭ͜ͱ͸Ͱ͖ͳ͍ let channel: AsyncChannel Task { for await _ in channel { let total = await logger.post() print("total : \(total)") } } Task { await channel.send(()) } "TZOD$IBOOFMΛ࢖͏

Slide 27

Slide 27 text

·ͱΊ 4XJGU$PODVSSFODZͱϨʔείϯσΟγϣϯ w 4XJGU$PODVSSFOUZ͸ϨʔείϯσΟγϣϯΛ๷͍Ͱ͘ΕΔ΋ͷͰ͸ͳ͍ w Ή͠Ζޮ཰Λ༏ઌͯ͠໰୊Λى͜͠΍͍͢࢓૊Έʹͳ͍ͬͯΔ w "DUPSSFFOUSBODZ w ಉ͡BDUPSಉ࢜ͷॲཧͰ΋ɺBXBJUͰڬΈࠐ·ΕΔՄೳੑ͕͋Δ w $PPQFSBUJWF5ISFBE1PPM w εϨουͰ࣮ߦ͞ΕΔॱ൪͸ɺ࣮ߦ։࢝͠Α͏ͱͨ͠ॱ൪ͱ͸ݶΒͳ͍

Slide 28

Slide 28 text

·ͱΊ ϨʔείϯσΟγϣϯ΁ͷରԠ w ہॴతʹ͸ҰͭͷBDUPSͷதͰBTZODؔ਺Λ࢖Θͣʹ Ͳ͏ݺ͹Εͯ΋ෆ੔߹͕ى͖ͳ͍ঢ়ଶΛ࡞Δ w BTZODؔ਺Λ૊Έ߹Θͤͳ͍ͱ͍͚ͳ͚Ε͹ɺ ΫϦςΟΧϧηΫγϣϯ͕ಉ࣌ʹ࣮ߦ͞Εͳ͍Α͏ʹߟྀ࣮ͯ͠૷͢Δ

Slide 29

Slide 29 text

ࢀߟ w 88%$ w .FFUBTZODBXBJUJO4XJGU w 1SPUFDUNVUBCMFTUBUFXJUI4XJGUBDUPST w 4XJGUDPODVSSFODZ#FIJOEUIFTDFOFT