GCD issues in Xcode 8 with Swift 2.3 #83

Closed
opened 2025-12-29 15:23:51 +01:00 by adam · 17 comments
Owner

Originally created by @gauravstomar on GitHub (Sep 22, 2016).

[CoreStore: Assertion Failure] BaseDataTransaction.swift:58 create
↪︎ Attempted to create an entity of type 'MediaMO' outside its designated queue.

Originally created by @gauravstomar on GitHub (Sep 22, 2016). ❗ [CoreStore: Assertion Failure] BaseDataTransaction.swift:58 create ↪︎ Attempted to create an entity of type 'MediaMO' outside its designated queue.
adam closed this issue 2025-12-29 15:23:51 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Sep 22, 2016):

Hi, can you show how your transaction is set up?

@JohnEstropia commented on GitHub (Sep 22, 2016): Hi, can you show how your transaction is set up?
Author
Owner

@gauravstomar commented on GitHub (Sep 22, 2016):

CoreStore.beginAsynchronous { (transaction) -> Void in
    let media = transaction.create(Into(MediaMO))
    media.name = "Image.png"
    media.url = url
    transaction.commit()
 }
@gauravstomar commented on GitHub (Sep 22, 2016): ``` CoreStore.beginAsynchronous { (transaction) -> Void in let media = transaction.create(Into(MediaMO)) media.name = "Image.png" media.url = url transaction.commit() } ```
Author
Owner

@JohnEstropia commented on GitHub (Sep 23, 2016):

Hmm I can't find anything wrong with your code, but I can't reproduce this with the test cases and the demo app. Can you isolate the conditions to reproduce this assertion failure? If you can edit the demo app to reproduce this it would greatly help

@JohnEstropia commented on GitHub (Sep 23, 2016): Hmm I can't find anything wrong with your code, but I can't reproduce this with the test cases and the demo app. Can you isolate the conditions to reproduce this assertion failure? If you can edit the demo app to reproduce this it would greatly help
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

Sure

@gauravstomar commented on GitHub (Sep 23, 2016): _Sure_
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

Its even crashing while fetching a record, same GCD issue. There is no specific scenario its quite random.

CoreStore.beginAsynchronous({ (transaction) in
    var mediaMO: MediaMO!
    mediaMO = CoreStore.fetchOne(From(MediaMO), Where("mediaId == \(fileId)"))
})

[CoreStore: Assertion Failure] DataStack+Querying.swift:126 fetchOne
↪︎ Attempted to fetch from a 'CoreStore.DataStack' outside the main thread.

@gauravstomar commented on GitHub (Sep 23, 2016): Its even crashing while fetching a record, same GCD issue. There is no specific scenario its quite random. ``` CoreStore.beginAsynchronous({ (transaction) in var mediaMO: MediaMO! mediaMO = CoreStore.fetchOne(From(MediaMO), Where("mediaId == \(fileId)")) }) ``` ❗ [CoreStore: Assertion Failure] DataStack+Querying.swift:126 fetchOne ↪︎ Attempted to fetch from a 'CoreStore.DataStack' outside the main thread.
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

Surprisingly adding it main queue fix the same. Any help?

CoreStore.beginAsynchronous({ (transaction) in
    var mediaMO: MediaMO!
    dispatch_async(dispatch_get_main_queue()) {
        mediaMO = CoreStore.fetchOne(From(MediaMO), Where("mediaId == \(fileId)"))
    }
})
@gauravstomar commented on GitHub (Sep 23, 2016): Surprisingly adding it main queue fix the same. Any help? ``` CoreStore.beginAsynchronous({ (transaction) in var mediaMO: MediaMO! dispatch_async(dispatch_get_main_queue()) { mediaMO = CoreStore.fetchOne(From(MediaMO), Where("mediaId == \(fileId)")) } }) ```
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

Same crashing for;

        guard let allClaimsData = CoreStore.fetchAll(From(MediaMO), Where("isSynced == %@", false)) else {
            return
        }

[CoreStore: Assertion Failure] DataStack+Querying.swift:160 fetchAll
↪︎ Attempted to fetch from a 'CoreStore.DataStack' outside the main thread.

But it worked when adding

        dispatch_async(dispatch_get_main_queue()) {
            guard let allClaimsData = CoreStore.fetchAll(From(ClaimsMO), Where("isSyncedChecklist == %@", false)) else {
                return
            }
        }

Any guesses?

@gauravstomar commented on GitHub (Sep 23, 2016): Same crashing for; ``` guard let allClaimsData = CoreStore.fetchAll(From(MediaMO), Where("isSynced == %@", false)) else { return } ``` ❗ [CoreStore: Assertion Failure] DataStack+Querying.swift:160 fetchAll ↪︎ Attempted to fetch from a 'CoreStore.DataStack' outside the main thread. But it worked when adding ``` dispatch_async(dispatch_get_main_queue()) { guard let allClaimsData = CoreStore.fetchAll(From(ClaimsMO), Where("isSyncedChecklist == %@", false)) else { return } } ``` Any guesses?
Author
Owner

@JohnEstropia commented on GitHub (Sep 23, 2016):

That just means you're calling DataStack methods from background queues. DataStack methods should be called from the main queue. Check that your CoreStore.begin***(), CoreStore.fetchAll(), etc are called from the main queue.

@JohnEstropia commented on GitHub (Sep 23, 2016): That just means you're calling DataStack methods from background queues. DataStack methods should be called from the main queue. Check that your `CoreStore.begin***()`, `CoreStore.fetchAll()`, etc are called from the main queue.
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

The same code was working fine for Swift 2.2, any catch?

@gauravstomar commented on GitHub (Sep 23, 2016): The same code was working fine for Swift 2.2, any catch?
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

We are using the same since last 4 months, it was working like a charm. Its really a wonderful and hassle free Core Data wrapper but some how its crashing intermittently after migrating to Xcode 8/Swift 2.3

Its quite weird to add dispatch_async(dispatch_get_main_queue()) before each CoreStore.begin***(), CoreStore.fetchAll(), etc. There should be some kind of catch we are not getting :(

@gauravstomar commented on GitHub (Sep 23, 2016): We are using the same since last 4 months, it was working like a charm. Its really a wonderful and hassle free Core Data wrapper but some how its crashing intermittently after migrating to Xcode 8/Swift 2.3 Its quite weird to add `dispatch_async(dispatch_get_main_queue())` before each `CoreStore.begin***()`, `CoreStore.fetchAll()`, etc. There should be some kind of catch we are not getting :(
Author
Owner

@JohnEstropia commented on GitHub (Sep 23, 2016):

Can you try to add assert(NSThread.isMainThread()) before your CoreStore.begin..., CoreStore.fetch... calls? If that assertion fails then all I can advise is to check why your methods are now running on a background thread (maybe you missed something during Swift 2.3 migration?)

@JohnEstropia commented on GitHub (Sep 23, 2016): Can you try to add `assert(NSThread.isMainThread())` before your `CoreStore.begin...`, `CoreStore.fetch...` calls? If that assertion fails then all I can advise is to check why your methods are now running on a background thread (maybe you missed something during Swift 2.3 migration?)
Author
Owner

@gauravstomar commented on GitHub (Sep 23, 2016):

May be it will work;

extension CoreStore {
    public static func beginAsynchronous(closure: (transaction: AsynchronousDataTransaction) -> Void) {
        dispatch_async(dispatch_get_main_queue()) {
            CoreStore.beginAsynchronous(closure)
        }
    }
}

@gauravstomar commented on GitHub (Sep 23, 2016): May be it will work; ``` extension CoreStore { public static func beginAsynchronous(closure: (transaction: AsynchronousDataTransaction) -> Void) { dispatch_async(dispatch_get_main_queue()) { CoreStore.beginAsynchronous(closure) } } } ```
Author
Owner

@JohnEstropia commented on GitHub (Sep 23, 2016):

I really suggest you investigate first why your methods are running on the background queue after migrating to Swift 2.3. CoreStore's DataStack methods had always checked for main thread execution, and if it's failing assertions now then that just means your code had an unintended change somewhere else. Can you send a stack trace from when you hit the assertion failure?

@JohnEstropia commented on GitHub (Sep 23, 2016): I really suggest you investigate first why your methods are running on the background queue after migrating to Swift 2.3. CoreStore's `DataStack` methods had always checked for main thread execution, and if it's failing assertions now then that just means your code had an unintended change somewhere else. Can you send a stack trace from when you hit the assertion failure?
Author
Owner

@JohnEstropia commented on GitHub (Sep 23, 2016):

@gauravstomar Just to make sure, I need to know what happens if you put assert(NSThread.isMainThread()) before calling beginAsync or fetchAll functions.

assert(NSThread.isMainThread())
CoreStore.beginAsynchronous({ (transaction) in
    // ...
}
assert(NSThread.isMainThread())
let objects = CoreStore.fetchAll( // ...

Please tell if the assert fails for you or not.

@JohnEstropia commented on GitHub (Sep 23, 2016): @gauravstomar Just to make sure, I need to know what happens if you put `assert(NSThread.isMainThread())` before calling beginAsync or fetchAll functions. ``` swift assert(NSThread.isMainThread()) CoreStore.beginAsynchronous({ (transaction) in // ... } ``` ``` swift assert(NSThread.isMainThread()) let objects = CoreStore.fetchAll( // ... ``` Please tell if the assert fails for you or not.
Author
Owner

@gauravstomar commented on GitHub (Sep 24, 2016):

It fails! It usually happens we user CoreStore with Alamofire

@gauravstomar commented on GitHub (Sep 24, 2016): It fails! It usually happens we user CoreStore with Alamofire
Author
Owner

@JohnEstropia commented on GitHub (Sep 24, 2016):

If the assert(NSThread.isMainThread()) outside CoreStore fails, then you'll have make changes to your code so DataStack calls happen on the main thread. It seems you can tell Alamofire which queue run responses on. See https://github.com/Alamofire/Alamofire/issues/1319

@JohnEstropia commented on GitHub (Sep 24, 2016): If the `assert(NSThread.isMainThread())` outside CoreStore fails, then you'll have make changes to your code so DataStack calls happen on the main thread. It seems you can tell Alamofire which queue run responses on. See https://github.com/Alamofire/Alamofire/issues/1319
Author
Owner

@popwarfour commented on GitHub (Nov 18, 2016):

cs_isCurrentExecutionContext() -> Bool.

Looks like DispatchQueue.getSpecific(key: Static.specificKey) is return nil after doing a Alamofire request. But does not return nil if no Alamofire request is made. Forcing Almofire to return on the main queue AND/OR force dispatching on the main queue don't solve the issue.

I'm not familiar enough with GCD but is this expected behavior?

Line 63ish in DispatchQueue+CoreStore.swift, swift3_develop branch

@popwarfour commented on GitHub (Nov 18, 2016): cs_isCurrentExecutionContext() -> Bool. Looks like DispatchQueue.getSpecific(key: Static.specificKey) is return nil after doing a Alamofire request. But does not return nil if no Alamofire request is made. Forcing Almofire to return on the main queue AND/OR force dispatching on the main queue don't solve the issue. I'm not familiar enough with GCD but is this expected behavior? Line 63ish in DispatchQueue+CoreStore.swift, swift3_develop branch
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#83