Share
Embed
(iOSDC Japan 2023) ActorでCoreDataをスレッドから解放しよう
このスライドは、iOSDC Japan 2023 でトークを行ったものです。
https://fortee.jp/iosdc-japan-2023/proposal/240c16ac-498a-4d17-a43a-f34f0fdbe041
Himeshi
September 05, 2023
Transcript
70 slides
-
͜ͷίʔυ҆શͳ࣮͔ʁ 9 class CoreDataController { private var entity: CoreDataEntity? =
nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } -
10 class CoreDataController { private var entity: CoreDataEntity? = nil
private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } .BOBHFEPCKFDUDPOUFYUΛൃߦ .BOBHFEPCKFDUΛੜɺอଘ ͜ͷίʔυ҆શͳ࣮͔ʁ -
͜ͷ࣮εϨουηʔϑͰͳ͍ 11 class CoreDataController { private var entity: CoreDataEntity? =
nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } initͱҟͳΔεϨου͔Β ΞΫηε͍͚ͯ͠ͳ͍ -
͜ͷ࣮εϨουηʔϑͰͳ͍ 12 class CoreDataController { private var entity: CoreDataEntity? =
nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } /4.BOBHFE0CKFDUͱ/4.BOBHFE0CKFDU$POUFYU εϨουηʔϑͰͳ͍ɻ -
͜ͷ࣮εϨουηʔϑͰͳ͍ 13 class CoreDataController { private var entity: CoreDataEntity? =
nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } εϨουηʔϑͰͳ͍ΦϒδΣΫτΛ ϓϩύςΟͱͯ͠อ͍࣋ͯ͠Δɻ ˠҟͳΔεϨου͔ΒΞΫηε͢ΔͱεϨουҧ /4.BOBHFE0CKFDUͱ/4.BOBHFE0CKFDU$POUFYU εϨουηʔϑͰͳ͍ɻ -
$PSF%BUBͷεϨουҧͱ w /4.BOBHFE0CKFDUɺ/4.BOBHFE0CKFDU$POUFYU ͦΕΛੜͨ͠εϨουͷ֎͔ΒΞΫηε͢ΔͱεϨουҧɻ w σʔλͷෆ߹ΫϥογϡΛҾ͖ى͜͢ɻ w ͜ΕΒͷΦϒδΣΫτΛੜͨ͠εϨουͷ֎ʹ࣋ͪग़͞ͳ͍͜ͱ Λ"QQMFͷυΩϡϝϯτٻΊ͍ͯΔɻ 15
"QQMF%FWFMPQFS%PDVNFOUBUJPOʰ/4.BOBHFE0CKFDU$POUFYUʱΑΓ -
"DUPSʹ͢Εେৎʁ 16 actor CoreDataController { private var entity: CoreDataEntity? =
nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } -
17 w "DUPSʹ͢Εσʔλڝ߹͠ͳ͍ͣʜ actor CoreDataController { private var entity: CoreDataEntity?
= nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } "DUPSʹ͢Εେৎʁ -
18 w "DUPSʹ͢Εσʔλڝ߹͠ͳ͍ͣʜ actor CoreDataController { private var entity: CoreDataEntity?
= nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } ͜ͷ࣮$PODVSSFODZXBSOJOHΛग़͞ͳ͍ɻ "DUPSʹ͢Εେৎʁ -
actor CoreDataController { private var entity: CoreDataEntity? = nil private
let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } 19 w "DUPSCPVOEBSZ֎͔Β͜ͷBDUPSΛͬͯΈΔɻ func testCallCoreDataController() async throws { let controller = CoreDataController( container: container ) try await controller.configure() } "DUPSʹ͢Εେৎʁ -
actor CoreDataController { private var entity: CoreDataEntity? = nil private
let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } 20 w ͜ͷ࣮εϨουҧΛҾ͖ى͜͢ɻ ͜͜ͰΫϥογϡ "DUPSʹ͢Εେৎʁ -
actor CoreDataController { private var entity: CoreDataEntity? = nil private
let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } "DUPSεϨουಉҰੑΛอূ͠ͳ͍ 21 w JOJUͱDPOpHVSF͕ݺΕΔεϨουɺ࣮ࡍʹҟͳΔɻ func testCallCoreDataController() async throws { let controller = CoreDataController( container: container ) try await controller.configure() } -
$PSF%BUBͷεϨουҧͱ w /4.BOBHFE0CKFDUɺ/4.BOBHFE0CKFDU$POUFYU ͦΕΛੜͨ͠εϨουͷ֎͔ΒΞΫηε͢ΔͱεϨουҧɻ w σʔλͷෆ߹ΫϥογϡΛҾ͖ى͜͢ɻ w ͜ΕΒͷΦϒδΣΫτΛੜͨ͠εϨουͷ֎ʹ࣋ͪग़͞ͳ͍͜ͱ Λ"QQMFͷυΩϡϝϯτٻΊ͍ͯΔɻ w
"DUPSεϨουͷಉҰੑΛอূ͠ͳ͍ɻ w .BOBHFE0CKFDU͕ੜεϨουͷ֎ʹ࣋ͪग़͞Εͯ͠·͏ɻ 22 -
class CoreDataController { private var entityID: NSManagedObjectID? = nil private
let container: NSPersistentContainer func update(_ newName: String) async throws { guard let entityID else { return } let moc = container.newBackgroundContext() try await moc.perform { let entity = try? moc.existingObject(with: entityID) as? CoreDataEntity entity?.name = newName try moc.save() } } } /4.BOBHFE0CKFDU*%Λ͏ 24 -
class CoreDataController { private var entityID: NSManagedObjectID? = nil private
let container: NSPersistentContainer func update(_ newName: String) async throws { guard let entityID else { return } let moc = container.newBackgroundContext() try await moc.perform { let entity = try? moc.existingObject(with: entityID) as? CoreDataEntity entity?.name = newName try moc.save() } } } /4.BOBHFE0CKFDU*%Λ͏ 25 ࣮ࡍͷNBOBHFEPCKFDUͷܕͷ͔ΘΓʹ /4.BOBHFE0CKFDU*%Λ༻ .BOBHFEPCKFDUʹΞΫηε͢ΔʹGFUDI͢Δ -
class CoreDataController { private var entityID: NSManagedObjectID? = nil private
let container: NSPersistentContainer func update(_ newName: String) async throws { guard let entityID else { return } let moc = container.newBackgroundContext() try await moc.perform { let entity = try? moc.existingObject(with: entityID) as? CoreDataEntity entity?.name = newName try moc.save() } } } /4.BOBHFE0CKFDU*%Λ͏ 26 .BOBHFE0CKFDUʹΞΫηε͢Δʹ ຖճGFUDI͠ͳ͚ΕͳΒͳ͍ .BOBHFE0CKFDUͷܕใ͕ͳ͍ -
4FOEBCMFͱʁ w σʔλڝ߹͕ൃੜͤͣ҆શʹड͚͠Ͱ͖ΔܕΛද͢ϓϩτίϧɻ w ͲͷBDUPSDPOUFYU͔ΒΞΫηεͯ҆͠શɻ w ྫ͑ɺܕ4FOEBCMFɻ w ड͚࣌͠ʹίϐʔ͞ΕΔ͔Βɻ w
/4.BOBHFE0CKFDU/4.BOBHFE0CKFDU$POUFYU 4FOEBCMFͰͳ͍ɻ w ҟͳΔBDUPSDPOUFYU͔ΒΞΫηε͍͚ͯ͠ͳ͍ɻ 33 -
(MPCBMBDUPSͱʁ w ϓϩύςΟͷಉظΞΫηεΛಛఆͷBDUPSDPOUFYUʹ੍ݶ͢Δɻ w ྫʣ.BJO"DUPSΛద༻ͨ͠ϓϩύςΟɺ.BJO"DUPS͔ΒͷΈ ಉظΞΫηεͰ͖Δɻ w /PO4FOEBCMFͳܕʹHMPCBMBDUPSΛద༻͢Δͱɺ4FOEBCMFͳܕ ͱͯ͠ѻ͏͜ͱ͕Ͱ͖Δɻ w
(MPCBMBDUPSʹΑͬͯσʔλڝ߹͕ൃੜ͠ͳ͍͜ͱ͕อূ͞ΕΔ͔Βɻ 36 @MainActor var mainActorIsolatedValue: Int? -
(MPCBMBDUPSΛఆٛ͢Δ w .BOBHFE0CKFDU.0$Λ4FOEBCMFʹ͢ΔͨΊʹ HMPCBMBDUPSΛఆٛ͢Δɻ w (MPCBMBDUPSͱͯ͠ɺ$PSF%BUB"DUPSΛఆٛ͢Δɻ w 6*ͷӨڹΛ͙ͨΊɺ.BJO"DUPSΘͳ͍ɻ 37 @globalActor
public actor CoreDataActor { public static let shared = CoreDataActor() } -
.BOBHFE0CKFDUʹHMPCBMBDUPSΛద༻ w .BOBHFE0CKFDUͷܕʢ$PSF%BUB&OUJUZʣʹ$PSF%BUB"DUPSΛ ద༻͢Δɻ w ܕͷఆٛʹ!$PSF%BUB"DUPSΛ͚ͭΔ͚ͩɻ w ͜ΕͰ.BOBHFE0CKFDUΛ4FOEBCMFͳͷͱͯ͠ѻ͑Δɻ 38 @objc(CoreDataEntity)
@CoreDataActor public class CoreDataEntity: NSManagedObject {} -
.0$ʹHMPCBMBDUPSΛద༻ w $PSF%BUB"DUPSΛద༻ͨ͠ϥού $".BOBHFE0CKFDU$POUFYU Λ༻ҙ͠ɺϥούܦ༝Ͱ.0$Λར༻͢Δɻ 39 @CoreDataActor final class
CAManagedObjectContext { private let moc: NSManagedObjectContext init(_ moc: NSManagedObjectContext) { self.moc = moc } func fetch<…>(…) throws -> [T] { … } func save() throws { try moc.save() } func delete(_ object: NSManagedObject) { … } func insert<T: NSManagedObject>() -> T { … } } -
"DUPSͷ࣮ߦڥ 43 actor MyActor { … } w "DUPSɺσʔλڝ߹͕ൃੜ͠ͳ͍͜ͱΛอূ͢Δɻ w
ಉظతʹ࣮ߦ͢Δ໋ྩͷ·ͱ·ΓͰ͋Δʮ+PCʯΛҰ࣮ͭͣͭߦɻ -
"DUPSͷ࣮ߦڥ 44 actor MyActor { … } w "DUPSɺσʔλڝ߹͕ൃੜ͠ͳ͍͜ͱΛอূ͢Δɻ w
ಉظతʹ࣮ߦ͢Δ໋ྩͷ·ͱ·ΓͰ͋Δʮ+PCʯΛҰ࣮ͭͣͭߦɻ w ʮ+PCʯΛͲͷΑ͏ʹ࣮ߦ͢Δ͔ఆٛ͞Ε͍ͯͳ͍ɻ w σϑΥϧτͰɺ4XJGUϥϯλΠϜ͕+PCͷ࣮ߦڥΛఏڙ͢Δɻ w +PC͕࣮ߦ͞ΕΔεϨουࣗମຖճมΘΔՄೳੑ͕͋Δɻ -
$VTUPN"DUPS&YFDVUPSͱ w 4& 4XJGUͰ࣮ w "DUPSͷʮ+PCΛͲ͏࣮ߦ͢Δͷ͔ʯΛΧελϚΠζͰ͖Δɻ w +PCΛ࣮ߦ͢Δ&YFDVUPSΛ࣮͢Δɻ w
VOPXOFE&YFDVUPSͱͯ͠ɺ+PCΛ࣮ߦ͢Δ&YFDVUPSΛొ͢Δɻ 45 actor MyActor { nonisolated var unownedExecutor: UnownedSerialExecutor { ... } } -
$PSF%BUB&YFDVUPSͷ࣮ w KPCΛ/4.BOBHFE0CKFDU$POUFYUQFSGPSN @ Ͱ࣮ߦ͢Δɻ 47 final class CoreDataExecutor: SerialExecutor
{ private let container: MOCContainer func enqueue(_ job: consuming ExecutorJob) { let unownedJob = UnownedJob(job) container.perform { unownedJob.runSynchronously( on: self.asUnownedSerialExecutor() ) } } } -
$PSF%BUB&YFDVUPSͷ࣮ 48 final class CoreDataExecutor: SerialExecutor { private let container:
MOCContainer func enqueue(_ job: consuming ExecutorJob) { let unownedJob = UnownedJob(job) container.perform { unownedJob.runSynchronously( on: self.asUnownedSerialExecutor() ) } } } w KPCΛ/4.BOBHFE0CKFDU$POUFYUQFSGPSN @ Ͱ࣮ߦ͢Δɻ +PCΛQFSGPSNؔͰ࣮ߦ -
$PSF%BUB&YFDVUPSͷ࣮ 49 final class CoreDataExecutor: SerialExecutor { private let container:
MOCContainer func enqueue(_ job: consuming ExecutorJob) { let unownedJob = UnownedJob(job) container.perform { unownedJob.runSynchronously( on: self.asUnownedSerialExecutor() ) } } } w KPCΛ/4.BOBHFE0CKFDU$POUFYUQFSGPSN @ Ͱ࣮ߦ͢Δɻ &YFDVUPS+PC/PODPQZBCMFUZQF ʢ4XJGUͰಋೖʣ -
$PSF%BUB&YFDVUPSͷ࣮ 50 final class CoreDataExecutor: SerialExecutor { private let container:
MOCContainer func enqueue(_ job: consuming ExecutorJob) { let unownedJob = UnownedJob(job) container.perform { unownedJob.runSynchronously( on: self.asUnownedSerialExecutor() ) } } } w 4FSJBM&YFDVUPS4FOEBCMFͰ͋Δ͜ͱΛཁٻ͢Δɻ /4.BOBHFE0CKFDU$POUFYUΛ 4FOEBCMFͳͷͱͯ͠ѻ͏ͨΊͷίϯςφ -
.0$$POUBJOFSͷ࣮ w .0$ͷQFSGPSNΛεϨουηʔϑʹݺͿͨΊͷίϯςφ 51 final class MOCContainer: @unchecked Sendable {
private let persistentContainer: NSPersistentContainer let queue = DispatchQueue(label: "MOCContainer") lazy var moc: NSManagedObjectContext = persistentContainer.newBackgroundContext() init(_ persistentContainer: NSPersistentContainer) { self.persistentContainer = persistentContainer } func perform(_ block: @escaping @Sendable () -> Void) { queue.async { self.moc.perform(block) } } } -
$PSF%BUB&YFDVUPS͖ͭͮ w (MPCBMBDUPSʹ&YFDVUPSΛొ͢ΔͨΊʹɺTIBSFEΠϯελϯεΛ ༻ҙ͢Δɻ 52 extension CoreDataExecutor { @CoreDataActor var
moc: CAManagedObjectContext { .init(container.moc) } static var sharedExecutor = CoreDataExecutor.init(.shared) static var sharedUnownedExecutor: UnownedSerialExecutor { sharedExecutor.asUnownedSerialExecutor() } } -
(MPCBMBDUPSʹ&YFDVUPSΛొ w $PSF%BUB"DUPSͷVOPXOFE&YFDVUPSͱͯ͠ɺ $PSF%BUB&YFDVUPSͷTIBSFEΠϯελϯεΛฦ͢Α͏ʹ͢Δɻ w $PSF%BUB"DUPSʹର͢Δૢ࡞ͯ͢ɺ$PSF%BUB&YFDVUPS͕ཧ ͢Δ.0$ͷQFSGPSNؔͰ࣮ߦ͞ΕΔΑ͏ʹͳͬͨɻ 53 extension CoreDataActor
{ public nonisolated var unownedExecutor: UnownedSerialExecutor { CoreDataExecutor.sharedUnownedExecutor } } -
͜͜·Ͱͷ·ͱΊ .BOBHFE0CKFDUͱ.0$ʹରͯ͠ҎԼͷ͜ͱΛߦͳͬͨɻ w 4FOEBCMFʹ͢Δɻ w .BOBHFE0CKFDUʜ(MPCBMBDUPSΛܕʹద༻͢Δɻ w .0$ʜ(MPCBMBDUPSΛద༻ͨ͠ϥούΛ࣮ɻ w (MPCBMBDUPSͷ+PCͷ࣮ߦΛ੍ݶɻ
w $VTUPN"DUPS&YFDVUPSΛར༻͢Δɻ w &YFDVUPSͷڞ௨.0$ͷQFSGPSNؔͰͯ͢ͷ+PCΛ࣮ߦɻ 54 -
͜͜·Ͱͷ·ͱΊ .BOBHFE0CKFDUͱ.0$ʹରͯ͠ҎԼͷ͜ͱΛߦͳͬͨɻ w 4FOEBCMFʹ͢Δɻ w .BOBHFE0CKFDUʜ(MPCBMBDUPSΛܕʹద༻͢Δɻ w .0$ʜ(MPCBMBDUPSΛద༻ͨ͠ϥούΛ࣮ɻ w (MPCBMBDUPSͷ+PCͷ࣮ߦΛ੍ݶɻ
w $VTUPN"DUPS&YFDVUPSΛར༻͢Δɻ w &YFDVUPSͷڞ௨.0$ͷQFSGPSNؔͰͯ͢ͷ+PCΛ࣮ߦɻ 55 -
͜͜·Ͱͷ·ͱΊ .BOBHFE0CKFDUͱ.0$ʹରͯ͠ҎԼͷ͜ͱΛߦͳͬͨɻ w 4FOEBCMFʹ͢Δɻ w .BOBHFE0CKFDUʜ(MPCBMBDUPSΛܕʹద༻͢Δɻ w .0$ʜ(MPCBMBDUPSΛద༻ͨ͠ϥούΛ࣮ɻ w (MPCBMBDUPSͷ+PCͷ࣮ߦΛ੍ݶɻ
w $VTUPN"DUPS&YFDVUPSΛར༻͢Δɻ w &YFDVUPSͷڞ௨.0$ͷQFSGPSNؔͰͯ͢ͷ+PCΛ࣮ߦɻ 56 -
$SFBUFૢ࡞ʢ$PSF%BUB"DUPSʣ w .0$ɺ$PSF%BUB&YFDVUPS͕ఏڙ͢Δ $".BOBHFE0CKFDU$POUFYUΦϒδΣΫτΛ༻͍Δɻ w $PSF%BUB"DUPSͳͷͰɺಉظతʹૢ࡞Ͱ͖Δɻ 58 @CoreDataActor func createObject()
throws -> Entity { let moc = CoreDataExecutor.sharedExecutor.moc let managedObject: Entity = moc.insert() try moc.save() return managedObject } -
@AnotherActor func createObject() throws -> Entity { let moc =
CoreDataExecutor.sharedExecutor.moc let managedObject: Entity = moc.insert() try moc.save() return managedObject } $SFBUFૢ࡞ʢ$PSF%BUB"DUPS֎ʣ 59 ίϯύΠϧΤϥʔ BXBJU͕ඞཁ w .BOBHFEPCKFDU͓Αͼ.0$ɺඇಉظΞΫηε͕ڧ੍͞ΕΔ -
$SFBUFૢ࡞ʢ$PSF%BUB"DUPS֎ʣ 60 @AnotherActor func createObject() async throws -> Entity {
let moc = await CoreDataExecutor.sharedExecutor.moc let managedObject: Entity = await moc.insert() try await moc.save() return managedObject } w .BOBHFEPCKFDU͓Αͼ.0$ɺඇಉظΞΫηε͕ڧ੍͞ΕΔ -
3FBEૢ࡞ʢ$PSF%BUB"DUPSʣ 61 @CoreDataActor func fetchObject() throws -> Entity? { let
moc = CoreDataExecutor.sharedExecutor.moc let fetchRequest = Entity.fetchRequest() fetchRequest.entity = Entity.entity() let managedObjects = try moc.fetch(fetchRequest) return managedObjects.first } w .0$ɺ$PSF%BUB&YFDVUPS͕ఏڙ͢Δ $".BOBHFE0CKFDU$POUFYUΦϒδΣΫτΛ༻͍Δɻ w $PSF%BUB"DUPSͳͷͰɺಉظతʹૢ࡞Ͱ͖Δɻ -
3FBEૢ࡞ʢ$PSF%BUB"DUPS֎ʣ w /4'FUDI3FRVFTU4FOEBCMFͰͳ͍ɻ w $PSF%BUB"DUPSͰΈཱͯ.0$ʹ͢͜ͱ͕ඞཁɻ 62 @AnotherActor func fetchObject() async
throws -> Entity? { let moc = await CoreDataExecutor.sharedExecutor.moc let managedObjects = try await Task { @CoreDataActor in let fetchRequest = Entity.fetchRequest() fetchRequest.entity = Entity.entity() return try moc.fetch(fetchRequest) }.value return managedObjects.first } -
6QEBUFૢ࡞ʢ$PSF%BUB"DUPSʣ 63 @CoreDataActor func updateObject(managedObject: Entity) throws { // nameΛupdate͢Δ
let moc = CoreDataExecutor.sharedExecutor.moc managedObject.name = "Jiro" try moc.save() } w .0$ɺ$PSF%BUB&YFDVUPS͕ఏڙ͢Δ $".BOBHFE0CKFDU$POUFYUΦϒδΣΫτΛ༻͍Δɻ w $PSF%BUB"DUPSͳͷͰɺಉظతʹૢ࡞Ͱ͖Δɻ -
6QEBUFૢ࡞ʢ$PSF%BUB"DUPS֎ʣ w 4FUUFSBDUPS֎ʹެ։͞Εͳ͍ͨΊɺ$PSF%BUB"DUPSͰͷૢ࡞ ͕ڧ੍͞ΕΔɻ 64 @AnotherActor func updateObject(managedObject: Entity) async
throws { // nameΛupdate͢Δ try await Task { @CoreDataActor in let moc = CoreDataExecutor.sharedExecutor.moc managedObject.name = "Jiro" try moc.save() }.value } -
%FMFUFૢ࡞ʢ$PSF%BUB"DUPSʣ 65 @CoreDataActor func deleteObject(managedObject: Entity) throws { let moc
= CoreDataExecutor.sharedExecutor.moc moc.delete(managedObject) try moc.save() } w .0$ɺ$PSF%BUB&YFDVUPS͕ఏڙ͢Δ $".BOBHFE0CKFDU$POUFYUΦϒδΣΫτΛ༻͍Δɻ w $PSF%BUB"DUPSͳͷͰɺಉظతʹૢ࡞Ͱ͖Δɻ -
%FMFUFૢ࡞ʢ$PSF%BUB"DUPS֎ʣ 66 @AnotherActor func deleteObject(managedObject: Entity) async throws { let
moc = await CoreDataExecutor.sharedExecutor.moc await moc.delete(managedObject) try await moc.save() } w .BOBHFEPCKFDU͓Αͼ.0$ɺඇಉظΞΫηε͕ڧ੍͞ΕΔ -
࠷ॳͷίʔυͲ͏ͳͬͨͷ͔ 67 class CoreDataController { private var entity: CoreDataEntity? =
nil private let moc: NSManagedObjectContext init(container: NSPersistentContainer) { self.moc = container.newBackgroundContext() } func configure() throws { entity = CoreDataEntity(context: moc) try moc.save() } } -
͜͏ͳΓ·ͨ͠ 68 @CoreDataActor class CoreDataController { private var entity: CoreDataEntity?
= nil func configure() throws { let moc = CoreDataExecutor.sharedExecutor.moc entity = moc.insert() try moc.save() } } -
͜͏ͳΓ·ͨ͠ 69 @CoreDataActor class CoreDataController { private var entity: CoreDataEntity?
= nil func configure() throws { let moc = CoreDataExecutor.sharedExecutor.moc entity = moc.insert() try moc.save() } } w $MBTTࣗମΛ$PSF%BUB"DUPSʹॴଐͤ͞Δɻ w ҆શʹNBOBHFEPCKFDUΛϓϩύςΟͱͯ͠อ࣋ɻ