Thomas
10/10/2019, 5:41 PMThomas
10/10/2019, 5:42 PMKris Wong
10/10/2019, 5:49 PMThomas
10/10/2019, 5:50 PMKris Wong
10/10/2019, 5:53 PMThomas
10/10/2019, 6:01 PMkpgalligan
10/10/2019, 6:05 PMkpgalligan
10/10/2019, 6:06 PMKris Wong
10/10/2019, 6:07 PMKris Wong
10/10/2019, 6:08 PMkpgalligan
10/10/2019, 6:08 PMKris Wong
10/10/2019, 6:08 PMKris Wong
10/10/2019, 6:09 PMkpgalligan
10/10/2019, 6:09 PMinternal actual fun <B> backToFront(b: () -> B, job: (B) -> Unit) {
dispatch_async_f(dispatch_get_main_queue(), DetachedObjectGraph {
JobAndThing(job.freeze(), b())
}.asCPointer(), staticCFunction { it: COpaquePointer? ->
initRuntimeIfNeeded()
val result = DetachedObjectGraph<Any>(it).attach() as JobAndThing<B>
result.job(result.thing)
})
}
kpgalligan
10/10/2019, 6:10 PMdispatch_async_f(dispatch_get_main_queue()
is where you can get startedKris Wong
10/10/2019, 6:12 PMdispatch_async(dispatch_get_main_queue()) {
println("Hello world")
}
kpgalligan
10/10/2019, 6:12 PMStableRef
, you just need to be super careful that you’re in the right thread when you reference them againkpgalligan
10/10/2019, 6:13 PMKris Wong
10/10/2019, 6:14 PMThomas
10/10/2019, 6:14 PMdispatch_async_f
, is it correct that I can not access request
and didReceiveResponse
from my example? Would I need to use DetachedObjectGraph
to use it?Thomas
10/10/2019, 6:15 PMThomas
10/10/2019, 6:17 PMkpgalligan
10/10/2019, 6:19 PMThomas
10/10/2019, 6:20 PMHowever, what mutable state? You’re trying to update the db? Is that mutable? I’m confused.I might have used the wrong term here. What I meant is that I would like to pass the result from the
productsRequest
to the main thread. Then on the main thread I can update the UI and database.Thomas
10/10/2019, 6:26 PMoverride fun productsRequest(request: SKProductsRequest, didReceiveResponse: SKProductsResponse) {
initRuntimeIfNeeded()
dispatch_async(NSOperationQueue.mainQueue) {
// On main thread and can use request and didReceiveResponse without exceptions.
}
}
So if I understand correctly this is only possible because request and didReceiveResponse are ObjC objects. If they were Kotlin objects, you would need to freeze them or detach/attach them?Kris Wong
10/10/2019, 6:32 PMKris Wong
10/10/2019, 6:32 PMkpgalligan
10/10/2019, 6:40 PMkpgalligan
10/10/2019, 6:43 PMThomas
10/10/2019, 7:49 PMThomas
10/11/2019, 8:03 PMdispatch_async
worked fine for me yesterday, but now it is crashing with a EXC_BAD_ACCESS. See attached screenshot. Do you have any idea what could be wrong? Really appreciate your help, sorry if I ask too many questions!Thomas
10/11/2019, 8:04 PMThomas
10/11/2019, 8:12 PMkpgalligan
10/11/2019, 8:17 PMrequest/didReceiveResponse
are 2 things that may be problematic, but it could also be the parent class itselfThomas
10/11/2019, 8:21 PMval productRequest = SKProductsRequest(productIds.toSet().freeze())
productRequest.delegate = RequestDelegate(cont, database)
// Send the request to the App Store.
productRequest.start()
it could also be the parent class itselfIf you mean the RequestDelegate class, could it be that I need to keep a reference to it myself as well?
kpgalligan
10/11/2019, 8:34 PMRequestDelegate
instance is touched by multiple threads, especially since you’re dispatching to the main thread from inside one of its methods.kpgalligan
10/11/2019, 8:35 PMval productRequest = SKProductsRequest(productIds.toSet().freeze())
productRequest.delegate = RequestDelegate(cont, database).freeze()
// Send the request to the App Store.
productRequest.start()
kpgalligan
10/11/2019, 8:35 PMThomas
10/11/2019, 8:36 PMkpgalligan
10/11/2019, 8:39 PMkpgalligan
10/11/2019, 8:39 PMThomas
10/11/2019, 8:40 PMThomas
10/11/2019, 8:41 PMkpgalligan
10/11/2019, 8:45 PMkpgalligan
10/11/2019, 8:46 PMkpgalligan
10/11/2019, 8:46 PMkpgalligan
10/11/2019, 8:46 PMStableRef
, and only unpack it when back in the main threadThomas
10/11/2019, 8:48 PMkpgalligan
10/11/2019, 8:53 PMRequestDelegate
without freezing the continuation, but only if you’re super careful about only touching the continuation in the main thread (or whatever thread you originally had the continuation in).kpgalligan
10/11/2019, 8:54 PMThomas
10/12/2019, 10:22 AMThomas
10/12/2019, 10:22 AMkpgalligan
10/12/2019, 11:56 AMThomas
10/12/2019, 2:11 PMkpgalligan
10/12/2019, 2:13 PMThomas
10/12/2019, 2:17 PMThomas
10/12/2019, 2:18 PMkpgalligan
10/12/2019, 3:26 PMdispatch_async(NSOperationQueue.mainQueue) { }
kpgalligan
10/12/2019, 3:28 PM{ }
creates an object instance that represents the operation. That is created and “exists” in the background thread. Inside of dispatch_async
, that operation is scheduled to be run on the main thread. The main thread may loop through to that operation while the caller is exiting it’s context.kpgalligan
10/12/2019, 3:29 PMkpgalligan
10/12/2019, 3:30 PMkpgalligan
10/12/2019, 3:33 PM{ }
is represented by an object, just like everything else (https://github.com/JetBrains/kotlin/blob/master/spec-docs/function-types.md). If not frozen, it can have the same concurrency issues as everything else. The trick is, if you capture state in a lambda, and you freeze the lambda, you’ll freeze the captured state as well.Thomas
10/12/2019, 10:35 PMThomas
10/12/2019, 10:39 PMkpgalligan
10/12/2019, 10:39 PMThomas
10/12/2019, 10:40 PMThomas
10/12/2019, 10:41 PMkpgalligan
10/12/2019, 10:43 PMThomas
10/12/2019, 10:55 PMThomas
01/14/2020, 8:09 PM