Invoke DataStack.fetchExisting from a background thread #143

Closed
opened 2025-12-29 15:25:27 +01:00 by adam · 3 comments
Owner

Originally created by @ujamshy on GitHub (Jun 7, 2017).

i need to access a managed object received from ListMonitor and process it on a background thread.
General scheme is:
onDidInsertObject { object in // this is called on the main queue
localQueue.async { // doing work on a background queue
let localObject = self.dataStack.fetchExisting(object.objectId)
// access localObject properties (no modifications)
}
}
This will randomly cause crash when accessing the localObject properties.
Can we invoke DataStack.fetchExisting on a background thread, and if not what is the suggested scheme to avoid processing on the main thread.
thanks.

Originally created by @ujamshy on GitHub (Jun 7, 2017). i need to access a managed object received from ListMonitor and process it on a background thread. General scheme is: onDidInsertObject { object in // this is called on the main queue localQueue.async { // doing work on a background queue let localObject = self.dataStack.fetchExisting(object.objectId) // access localObject properties (no modifications) } } This will randomly cause crash when accessing the localObject properties. Can we invoke DataStack.fetchExisting on a background thread, and if not what is the suggested scheme to avoid processing on the main thread. thanks.
adam added the question label 2025-12-29 15:25:27 +01:00
adam closed this issue 2025-12-29 15:25:27 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Jun 7, 2017):

Use a temporary UnsafeDataTransaction in your background thread:

onDidInsertObject { object in // this is called on the main queue
    localQueue.async { // doing work on a background queue
        let transaction = self.dataStack.beginUnsafe()
        let localObject = transaction.fetchExisting(object.objectId)
        // access localObject properties (no modifications)
    }
}

Make sure transaction isn't released while you are using your objects.
You can use withExtendedLifetime(...) for that:

    localQueue.async { // doing work on a background queue
        withExtendedLifetime(self.dataStack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in
            let localObject = transaction.fetchExisting(object.objectId)
            // access localObject properties (no modifications)
        }
    }
@JohnEstropia commented on GitHub (Jun 7, 2017): Use a temporary `UnsafeDataTransaction` in your background thread: ```swift onDidInsertObject { object in // this is called on the main queue localQueue.async { // doing work on a background queue let transaction = self.dataStack.beginUnsafe() let localObject = transaction.fetchExisting(object.objectId) // access localObject properties (no modifications) } } ``` Make sure `transaction` isn't released while you are using your objects. You can use `withExtendedLifetime(...)` for that: ```swift localQueue.async { // doing work on a background queue withExtendedLifetime(self.dataStack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in let localObject = transaction.fetchExisting(object.objectId) // access localObject properties (no modifications) } } ```
Author
Owner

@ujamshy commented on GitHub (Jun 7, 2017):

Thanks for your answer and for your awesome framework.
Just to make sure:
DataStack.fetchExisting should be always called on main queue, is it correct?

@ujamshy commented on GitHub (Jun 7, 2017): Thanks for your answer and for your awesome framework. Just to make sure: DataStack.fetchExisting should be always called on main queue, is it correct?
Author
Owner

@JohnEstropia commented on GitHub (Jun 7, 2017):

@ujamshy Yes, DataStack's methods are meant to be used in the main thread (except for the methods that create transactions). Basically, you just need to remember that

  • DataStack.fetchExisting(_:) : main queue only
  • AsynchronousDataTransaction.fetchExisting(_:) : within the transaction's queue only
  • SynchronousDataTransaction.fetchExisting(_:) : within the transaction's queue only
  • UnsafeDataTransaction.fetchExisting(_:) : any queue
@JohnEstropia commented on GitHub (Jun 7, 2017): @ujamshy Yes, `DataStack`'s methods are meant to be used in the main thread (except for the methods that create transactions). Basically, you just need to remember that - `DataStack.fetchExisting(_:)` : main queue only - `AsynchronousDataTransaction.fetchExisting(_:)` : within the transaction's queue only - `SynchronousDataTransaction.fetchExisting(_:)` : within the transaction's queue only - `UnsafeDataTransaction.fetchExisting(_:)` : any queue
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#143