Dispatch

RSS for tag

Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system using Dispatch.

Dispatch Documentation

Pinned Posts

Posts under Dispatch tag

30 Posts
Sort by:
Post not yet marked as solved
2 Replies
119 Views
Per my understanding of the DispatchQueue docs, and various WWDC videos on the matter, if one creates a queue in the following manner: let q = DisqpatchQueue( label: "my-q", qos: .utility, target: .global(qos: .userInteractive) ) then one should expect work items submitted via async() to effectively run at userInteractive QoS, as the target queue should provide a 'floor' on the effective QoS value (assuming no additional rules are in play, e.g. higher priority items have been enqueued, submitted work items enforce QoS, etc). In practice, however, this particular formulation does not appear to function that way, and the 'resolved' QoS value seems to be utility, contrary to what the potentially relevant documentation suggests. This behavior appears to be inconsistent with other permutations of queue construction, which makes it even more surprising. Here's some sample code I was experimenting with to check the behavior of queues created in various ways that I would expect to function analogously (in regards to the derived QoS value for the threads executing their work items): func test_qos_permutations() { // q1 let utilTargetingGlobalUIQ = DispatchQueue( label: "qos:util tgt:globalUI", qos: .utility, target: .global(qos: .userInitiated) ) let customUITargetQ = DispatchQueue( label: "custom tgt, qos: unspec, tgt:globalUI", target: .global(qos: .userInitiated) ) // q2 let utilTargetingCustomSerialUIQ = DispatchQueue( label: "qos:util tgt:customSerialUI", qos: .utility, target: customUITargetQ ) // q3 let utilDelayedTargetingGlobalUIQ = DispatchQueue( label: "qos:util tgt:globalUI-delayed", qos: .utility, attributes: .initiallyInactive ) utilDelayedTargetingGlobalUIQ.setTarget(queue: .global(qos: .userInitiated)) utilDelayedTargetingGlobalUIQ.activate() let queues = [ utilTargetingGlobalUIQ, utilTargetingCustomSerialUIQ, utilDelayedTargetingGlobalUIQ, ] for q in queues { q.async { Thread.current.name = q.label let threadQos = qos_class_self() print(""" q: \(q.label) orig qosClass: \(q.qos.qosClass) thread qosClass: \(DispatchQoS.QoSClass(rawValue: threadQos)!) """) } } } Running this, I get the following output: q: qos:util tgt:customSerialUI orig qosClass: utility thread qosClass: userInitiated q: qos:util tgt:globalUI-delayed orig qosClass: utility thread qosClass: userInitiated q: qos:util tgt:globalUI orig qosClass: utility thread qosClass: utility This test suggests that constructing a queue with an explicit qos parameter and targeting a global queue of nominally 'higher' QoS does not result in a queue that runs its items at the target's QoS. Perhaps most surprisingly is that if the target queue is set after the queue was initialized, you do get the expected 'QoS floor' behavior. Is this behavior expected, or possibly a bug?
Posted
by jamie_sq.
Last updated
.
Post marked as solved
3 Replies
374 Views
I was wondering if there is a way, while debugging, to observe the 'QoS boosting' behavior that is implemented in various places to provide priority inversion avoidance. The pthread_override_qos_class_start/end_np header comments specifically say that overrides aren't reflected in the qos_class_self() and pthread_get_qos_class_np() return values. As far as I can tell the 'CPU Report' UI in Xcode also does not reflect this information (perhaps for the reason the header comments call out). Is there a direct mechanism to observe this behavior? Presumably a heuristic empirical test could be done to compare throughput of a queue that should have its priority boosted and one that should not, but I would prefer a less opaque means of verification if possible. Thanks in advance!
Posted
by jamie_sq.
Last updated
.
Post not yet marked as solved
6 Replies
223 Views
Two different crash patterns -- one an abort, the other complaining about a lock being corrupt or owning thread having exited. The first one is: Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos.overcommit 0 libsystem_platform.dylib 0x18fc10244 _os_unfair_lock_corruption_abort + 88 1 libsystem_platform.dylib 0x18fc0b788 _os_unfair_lock_lock_slow + 332 2 libobjc.A.dylib 0x18f820c90 objc_sync_enter + 20 3 com.kithrup.TPProvider 0x100d2eee0 closure #3 in TPProvider.startProxy(options:completionHandler:) + 340 4 com.kithrup.TPProvider 0x100d2d980 thunk for @escaping @callee_guaranteed () -> () + 28 5 libdispatch.dylib 0x18fa31910 _dispatch_client_callout + 20 6 libdispatch.dylib 0x18fa34dc8 _dispatch_continuation_pop + 600 7 libdispatch.dylib 0x18fa48be4 _dispatch_source_latch_and_call + 420 8 libdispatch.dylib 0x18fa477b4 _dispatch_source_invoke + 832 9 libdispatch.dylib 0x18fa431f4 _dispatch_root_queue_drain + 392 10 libdispatch.dylib 0x18fa43a04 _dispatch_worker_thread2 + 156 11 libsystem_pthread.dylib 0x18fbdb0d8 _pthread_wqthread + 228 12 libsystem_pthread.dylib 0x18fbd9e30 start_wqthread + 8 while the other one is: Application Specific Information: BUG IN CLIENT OF LIBPLATFORM: os_unfair_lock is corrupt, or owner thread exited without unlocking Abort Cause 198194 Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos.overcommit 0 libsystem_platform.dylib 0x18fc10220 _os_unfair_lock_corruption_abort + 52 1 libsystem_platform.dylib 0x18fc0b788 _os_unfair_lock_lock_slow + 332 2 libobjc.A.dylib 0x18f820c90 objc_sync_enter + 20 3 com.kithrup.TPProvider 0x104e86ee0 closure #3 in TPProvider.startProxy(options:completionHandler:) +340 4 com.kithrup.TPProvider 0x104e85980 thunk for @escaping @callee_guaranteed () -> () + 28 5 libdispatch.dylib 0x18fa31910 _dispatch_client_callout + 20 6 libdispatch.dylib 0x18fa34dc8 _dispatch_continuation_pop + 600 7 libdispatch.dylib 0x18fa48be4 _dispatch_source_latch_and_call + 420 8 libdispatch.dylib 0x18fa477b4 _dispatch_source_invoke + 832 9 libdispatch.dylib 0x18fa431f4 _dispatch_root_queue_drain + 392 10 libdispatch.dylib 0x18fa43a04 _dispatch_worker_thread2 + 156 11 libsystem_pthread.dylib 0x18fbdb0d8 _pthread_wqthread + 228 12 libsystem_pthread.dylib 0x18fbd9e30 start_wqthread + 8 Our TPProvider, whenever it uses a dispatch queue, uses a custom one, so these are presumably system queues and locks. My best guess would be some XPC command took too long? But that's just WAG. Any ideas about what is actually going on?
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
0 Replies
320 Views
Hi everyone, I have an AR app that allows for collaborative sessions and synchronizes model state (e.g. rotation, can be changed via slider) using Multipeer Connectivity. The receiving peer parses the data and then uses DispatchQueue.main.async to update the UI (SwiftUI) and the model in SceneKit. Lately I have noticed that this synchronization seems to lag periodically. To analyze the issue better I compiled this minimal reproducible example: https://github.com/MrMuetze/MCSyncTest The repository includes a boiled down "Multipeer Connectivity" project that should make this issue reproducible on local devices (maybe even between one device and the simulator). I have also added a readme with a gif that shows the issue. The synchronization between devices worked like a treat for a long time but recently I have noticed that e.g. a rotation is not as smooth as before on the receiving device. A bit of debugging revealed that the messages are received quickly but then the work that needs to happen on the main thread is periodically delayed. In the example project the relevant code bit that should be executed on the main thread looks like this: func session(_: MCSession, didReceive data: Data, fromPeer _: MCPeerID) { print("received data") DispatchQueue.main.async { print("doing stuff") let doubleVal = data.to(type: Double.self) ?? 0.0 self.internalSliderValue = doubleVal self.sliderValue = doubleVal } } It updates a published variable sliderValue that is connected to a Slider and a Text UI element. Regularly (like every 500ms or so) the execution of work on the main thread seems to be delayed. After a short while all outstanding UI updates are executed at once which leads to visual stuttering. This can be observed by looking at the printed messages: ... received data <-- normal behavior doing stuff received data doing stuff received data doing stuff received data <-- hiccup starts received data received data received data doing stuff doing stuff doing stuff doing stuff received data <-- returns to normal behavior doing stuff received data doing stuff ... I have tried to change the "Quality of Service" to .userInteractive as well as limiting the number of messages that are sent in a certain timeframe (I tried one message every 100ms). Both changes have not helped and even with a much lower number of messages the periodic stuttering remains. Using DispatchQueue.main.sync is also not a solution right now. It does bring the sequence back into original order but the periodic "freeze" of the queue is prevalent there as well. This then leads to a "laggy" execution of what happened on the sending peer device. I am not very familiar with Profiling an app and using Instruments, but I have captured some timings in regards to the usage of the main thread and some backtraces. From what I can understand the workload of the written code should not be the issue, but rather an underlying system function or library. I can provide more information in regards to the backtraces if needed. Right now I can't really say what would be useful. Below is an image that shows the main thread usage at the very top. This happens when the slider lags as shown in the gif. I am working with Xcode 15.2 and run the app on iOS 17.3. For devices I use an iPad Pro (2nd gen.) and an iPhone 15 Pro. The issue happens in Debug as well as in Release mode. I can't quite say when the stuttering appeared initially. I wonder if anyone is aware of any changes to iOS or underlying frameworks that could have caused this issue. I am interested in any information about this, if the issue can be resolved or if I have to look for alternative workarounds. Let me know if I can add any additional information. Best regards! Bjoern
Posted
by MrMuetze.
Last updated
.
Post not yet marked as solved
1 Replies
284 Views
I'm looking for a fast and efficient way for user-space to send I/O to my driver. One way I'd have hoped to do this, was through a shared memory ring-buffer. In the WWDC19 presentation on System Extensions and DriverKit, at roughly 17:00, they mention an IOSharedDataQueueDispatchSource. This doesn't exist in the DriverKit API. An IODataQueueDispatchSource is available, but doesn't seem to be meant to be shared. In the old IOKit framework, there are similar IOSharedDataQueue and IODataQueue, but they are unavailable in DriverKit. So, what are my options for implementing a fast, efficient I/O path to my driver?
Posted
by baekalfen.
Last updated
.
Post marked as solved
3 Replies
678 Views
Hello! I'm developing a SDK and a customer is experiencing a very rare crash (happening for < 10 users) for which there are no clear repro steps. In the attached backtrace of the crash, there are two threads #13 and #17 which seem to be accessing the same part of the code (named MyMethod2 in the file). Thread #17 is the one crashing during deallocation of some protobuf objects. We designed MyMethod2 to be called by at most one thread at any point in time by using a serial DispatchQueue. My question is: can we tell for sure that the threads #13 and #17 shown in the file were executing that shared code simultaneously just by looking at the trace? If so, there'd be a concurrency bug in my code that I need to fix, but I haven't found anything suspicious. If on the other hand, these two threads were both used by the serial queue but at different times, then the problem is elsewhere. Thank you for your help! The two threads: Thread 13 name: Thread 13: 0 libsystem_kernel.dylib 0x00000001f61a0cb0 write (libsystem_kernel.dylib) 1 CoreFoundation 0x00000001aed14f68 fileWrite (CoreFoundation) 2 CoreFoundation 0x00000001aed14c40 CFWriteStreamWrite (CoreFoundation) 3 [MyHiddenAppName] 0x0000000107b81f8c NSOutputStream.write(_:) 4 [MyHiddenAppName] 0x0000000107ab6640 specialized MyMethod2 5 [MyHiddenAppName] 0x0000000107ab6cf0 partial apply for closure #1 in MyMethod1 6 [MyHiddenAppName] 0x0000000102ba0538 thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>:0) 7 libdispatch.dylib 0x00000001b6c4f6a8 _dispatch_call_block_and_release (libdispatch.dylib) [...] Thread 17 name: Thread 17 Crashed: 0 libswiftCore.dylib 0x00000001a8467d70 _swift_release_dealloc (libswiftCore.dylib) 1 libswiftCore.dylib 0x00000001a8469424 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) (libswiftCore.dylib) 2 [MyHiddenAppName] 0x0000000107a45b54 destroy for MyProtoStruct4 3 [MyHiddenAppName] 0x0000000107a55c64 outlined destroy of (MyProtoStruct2.OneOfEnum, MyProtoStruct2.OneOfEnum) 4 [MyHiddenAppName] 0x0000000107a4503c MyProtoStruct4._StorageClass.__deallocating_deinit 5 libswiftCore.dylib 0x00000001a8467d88 _swift_release_dealloc (libswiftCore.dylib) 6 libswiftCore.dylib 0x00000001a8469424 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) (libswiftCore.dylib) 7 [MyHiddenAppName] 0x0000000107a6a91c destroy for MyProtoStruct3 [...] 80 [MyHiddenAppName] 0x0000000107ab6108 specialized MyMethod2 81 [MyHiddenAppName] 0x0000000107ab6cf0 partial apply for closure #1 in MyMethod1 82 [MyHiddenAppName] 0x0000000102ba0538 thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>:0) 83 libdispatch.dylib 0x00000001b6c4f6a8 _dispatch_call_block_and_release (libdispatch.dylib) [...] crash_backtrace.txt
Posted Last updated
.
Post marked as solved
1 Replies
253 Views
I want to optimize file reading performance. I believe DispatchIO is the solution. Can anyone give some good pointers?
Posted
by imneo.
Last updated
.
Post not yet marked as solved
5 Replies
427 Views
When calling DispatchQueue.main.async or DispatchQueue.main.sync with a call to self without capturing self, I get a compiler error: Call to method 'asd' in closure requires explicit use of 'self' to make capture semantics explicit Since I usually use DispatchQueue.main.async, I'm now used to solving this error by capturing self like this: DispatchQueue.main.async { [self] in asd() } But this unfortunately doesn't seem to work with DispatchQueue.main.sync: DispatchQueue.main.async { [self] in asd() } This gives the compiler warning: Call to method 'asd' in closure requires explicit use of 'self' to make capture semantics explicit; this is an error in Swift 6 This warning only appears for DispatchQueue.main.sync and not for DispatchQueue.main.async. Why? How can I avoid having to prefix every method call with self. in this case?
Posted
by Nickkk.
Last updated
.
Post not yet marked as solved
1 Replies
916 Views
The Apple App Store is saying my react native mobile app crashes on launch. I don't experience the same in my dev environment, neither in VScode nor in Xcode. When I run the app in Xcode, it compiles and works as expected but I found a message in the console output that indicates a possible thread inversion. In the provided backtrace, it seems to be related to a WebSocket connection in my React Native app. My app starts at a login page. Once the user enters their credentials they click login and a call is made to the app server which is hosted on Heroku. I think I should review the code related to the mentioned thread (TID: 1269068) and identify where the -[UIApplication applicationState] is being called. ChatGPT is suggesting to make sure that this call, and any other UI-related calls, are wrapped within a dispatch to the main thread. My knowledge of reading the backtrace is limited and i'm unsure how to map the backtrace to my actual javascript code. I've added the backtrace below: Thread Performance Checker: Thread running at User-interactive quality-of-service class waiting on a lower QoS thread running at Default quality-of-service class. Investigate ways to avoid priority inversions PID: 78136, TID: 1269068 Backtrace ================================================================= 3 xp1 0x0000000100ae679c -[SRRunLoopThread runLoop] + 44 4 xp1 0x0000000100ae0cc4 +[NSRunLoop(SRWebSocket) SR_networkRunLoop] + 56 5 xp1 0x0000000100ae50cc -[SRProxyConnect _openConnection] + 72 6 xp1 0x0000000100ae4584 -[SRProxyConnect _configureProxy] + 916 7 xp1 0x0000000100ae3d78 -[SRProxyConnect openNetworkStreamWithCompletion:] + 92 8 xp1 0x0000000100ae8530 -[SRWebSocket open] + 624 9 xp1 0x0000000100754804 -[RCTReconnectingWebSocket start] + 148 10 xp1 0x0000000100742b08 -[RCTPackagerConnection init] + 416 11 xp1 0x0000000100742948 __49+[RCTPackagerConnection sharedPackagerConnection]_block_invoke + 36 12 libdispatch.dylib 0x000000010389993c _dispatch_client_callout + 16 13 libdispatch.dylib 0x000000010389b3dc _dispatch_once_callout + 84 14 xp1 0x00000001007428fc +[RCTPackagerConnection sharedPackagerConnection] + 88 15 xp1 0x00000001007d1afc -[RCTDevSettings initialize] + 164 16 xp1 0x000000010072df4c -[RCTModuleData _initializeModule] + 96 17 xp1 0x000000010072d89c -[RCTModuleData setUpInstanceAndBridge:] + 2168 18 xp1 0x000000010072f3b4 -[RCTModuleData instance] + 1168 19 xp1 0x00000001006d7074 -[RCTCxxBridge moduleForName:lazilyLoadIfNecessary:] + 712 20 xp1 0x00000001007382d4 -[RCTModuleRegistry moduleForName:lazilyLoadIfNecessary:] + 140 21 xp1 0x000000010073823c -[RCTModuleRegistry moduleForName:] + 48 22 xp1 0x00000001007e2ba8 -[RCTPerfMonitor devMenuItem] + 92 23 xp1 0x00000001007e2a74 -[RCTPerfMonitor initialize] + 88 24 xp1 0x000000010072df4c -[RCTModuleData _initializeModule] + 96 25 xp1 0x000000010072d89c -[RCTModuleData setUpInstanceAndBridge:] + 2168 26 xp1 0x000000010072f5ec __25-[RCTModuleData instance]_block_invoke + 44 27 xp1 0x0000000100793d20 RCTUnsafeExecuteOnMainQueueSync + 52 28 xp1 0x000000010072f254 -[RCTModuleData instance] + 816 29 xp1 0x00000001006db97c __49-[RCTCxxBridge _prepareModulesWithDispatchGroup:]_block_invoke + 156 30 libdispatch.dylib 0x00000001038980f0 _dispatch_call_block_and_release + 24 31 libdispatch.dylib 0x000000010389993c _dispatch_client_callout + 16 32 libdispatch.dylib 0x00000001038a96ac _dispatch_main_queue_drain + 1428 33 libdispatch.dylib 0x00000001038a9108 _dispatch_main_queue_callback_4CF + 40 34 CoreFoundation 0x00000001803ee1b4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 35 CoreFoundation 0x00000001803e88cc __CFRunLoopRun + 1936 36 CoreFoundation 0x00000001803e7d28 CFRunLoopRunSpecific + 572 37 GraphicsServices 0x000000018e7cdbc0 GSEventRunModal + 160 38 UIKitCore 0x00000001852bafdc -[UIApplication _run] + 868 39 UIKitCore 0x00000001852bec54 UIApplicationMain + 124 40 xp1 0x00000001004172e0 main + 96
Posted Last updated
.
Post not yet marked as solved
0 Replies
391 Views
Swift Concurrency Resources: DevForums tags: Concurrency The Swift Programming Language Concurrency > Concurrency documentation WWDC 2022 Session 110351 Eliminate data races using Swift Concurrency — This ‘sailing on the sea of concurrency’ talk is a great introduction to the fundamentals. WWDC 2021 Session 10134 Explore structured concurrency in Swift — The table that starts rolling out at around 25:45 is really helpful. Dispatch Resources: DevForums tags: Dispatch Dispatch documentation — Note that the Swift API and C API, while generally aligned, are different in many details. Make sure you select the right language at the top of the page. Dispatch man pages — While the standard Dispatch documentation is good, you can still find some great tidbits in the man pages. See Reading UNIX Manual Pages. Start by reading dispatch in section 3. WWDC 2015 Session 718 Building Responsive and Efficient Apps with GCD [1] WWDC 2017 Session 706 Modernizing Grand Central Dispatch Usage [1] Avoid Dispatch Global Concurrent Queues DevForums post Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] These videos may or may not be available from Apple. If not, the URL should help you locate other sources of this info.
Posted
by eskimo.
Last updated
.
Post marked as solved
2 Replies
357 Views
I have folder monitoring code using makeFileSystemObjectSource. The events are triggered for everything else, but not for when I edit a file with nano terminal command. Am I doing something wrong? Is it a bug? Is this intended and unfixable? Code sample: monitoredFolderFileDescriptor = open(currentlyMonitoredPath, O_EVTONLY) folderMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: monitoredFolderFileDescriptor, eventMask: .all, queue: .main) folderMonitorSource?.setEventHandler { // ... } folderMonitorSource?.setCancelHandler { // ... } folderMonitorSource?.resume()
Posted
by Iwan_ua.
Last updated
.
Post not yet marked as solved
5 Replies
483 Views
class CalculatorViewModel : NSObject, ObservableObject, Identifiable { var id = UUID() @Published var output = "Disconnected" @Published var connected = false @Published var databasePath = String() enum itemType : Int{ case angle = 1 case degree = 2 case grip1 = 3 case grip2 = 4 } struct test_Array: Identifiable { var id = UUID() var time: String var swingNum : Int var dataSeqInSwing: Int var timeStampInSeq: Double var itemType: Int var value: Double } @Published var testDBdata = [test_Array] () ..... private var centralManager: CBCentralManager? func connectCalculator() { output = "Connecting..." centralQueue = DispatchQueue(label: "test.discovery") centralManager = CBCentralManager(delegate: self, queue: centralQueue) } .... func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { ..... if characteristic.uuid == outputCharUUID, var data = characteristic.value { ..... DispatchQueue.main.async() { for index in tupleSets { strItemSets = index.components(separatedBy: ",") ....... var itemN = 1 for indexStr in strItemSets { self.golfDBdata[numDB].dataSeqInSwing = countItem. <= Error self.golfDBdata[numDB].itemType = itemN self.golfDBdata[numDB].value = Double(strItemSets[itemN]) ?? 0.0
Posted Last updated
.
Post marked as solved
6 Replies
971 Views
A handful of my customers have reported a consistent freeze in my app (smells like either a thread deadlock or an infinite recursion to me). It's working properly for most people, but if 3 people are reporting it to me that says to me that probably 300 are experiencing it but staying quiet. It happens every time they take a certain kind of action. But it never happens to me so I can't figure out what is breaking. No crash is happening, so I'm not getting any reports via Firebase. It doesn't appear to be related to their data, because they can have someone else use a different device, login to their account, download all of their data, and then successfully do the thing that freezes 100% of the time on their original device. I've got one of these customers set up on TestFlight so I can send them test versions of the app with some debug collection code. I created my own version of a tracelog and write a line to a file whenever I start/end a function. I've added those tracelog calls to a bunch of methods and classes (but not all). The action that causes the freeze is when they tap Edit on a record. What's supposed to happen is that I modally present a nav controller containing an EditBlahViewController. The trace logs show that the EditBlahViewController gets through viewDidLoad, viewWillAppear, two rounds of viewWillLayoutSubviews/viewDidLayoutSubviews... but then never gets to viewDidAppear. I've tried updating more and more functions/classes with the tracelog calls, but I can't find any infinite recursions. I've added tracelogs to all calls involving dispatching to other threads (especially synchronous dispatches to the main thread) but I don't see any deadlocks. Every dispatch to main starts and ends properly and then goes on to the next thing. User is on iOS 16.6.1 with an iPhone 12. I don't know what else to try. How can I debug this at a distance and figure out where the problem is?
Posted Last updated
.
Post not yet marked as solved
5 Replies
567 Views
In a thread titled “Avoid Dispatch Global Concurrent Queues” [1], Quinn links to a video from WWDC 2015 Session 718, “Building Responsive and Efficient Apps with GCD”. However, this video is not available from the Apple Developer Videos site; only a half dozen or so videos from 2015 are available. This same issue of the missing video came up about five years ago, when Quinn stated that the video had been mistakenly removed but had been restored. Now it’s gone again. :sad_face: Could this video be restored again, or at least its transcript? While I understand that Apple is focused on Swift concurrency, I need to maintain some Objective-C code that uses GCD, and in tracking down some performance issues, I would like to better understand the tradeoffs in the existing code and make improvements where I can. I don’t have the resources to reimplement the code in Swift right now. (More generally, why can't Apple just leave all these videos online indefinitely, for historical purposes at least? Couldn't the ones deemed “old and misleading” just be tagged with a banner like the legacy documentation has?) [1] I like to think of these valuable threads as “Quinn Technical Notes”; I have a page in my Notes app that holds links to the ones I’ve found.
Posted Last updated
.
Post not yet marked as solved
7 Replies
653 Views
Hi! I have a xcode workspace with first objectiveC framework (let’s call it framework#1). This framework has some singletons (+(instancetype)shared using the dispatch_once idiom. This code is pretty straight forward and used everywhere : + (instancetype)shared { static dispatch_once_t onceToken; static OGAKeyManager *instance = nil; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } I have a second framework (framework#2) in Swift that uses theses singletons (the framework#1 is added as do not embeed in the framework settings). And I have an application that uses both frameworks. If I make a breakpoint inside the dispatch_once alloc/init, I see that I enter 2 times : once when the shared method is called from framework#1 and another one when it’s called from framework#2. How is that even possible ? Isn't dispatch_once supposed to handle this ? I asked chatGPT, it points out to some objC/Swift interoperability, but honestly, I don't see what I can do to make it work correctly. There is no circular dependency (framwork#2 uses framwork#1, but framwork#1 has no clue of framwork#2 existence) Maybe it has something to do with sandbox, but I don't see how can it be. Does anyone experienced some weird behavior like this ? Thanks
Posted Last updated
.
Post not yet marked as solved
4 Replies
910 Views
I had 2 crash report from our customer. Both crash point is same but there is no my code on crash stack trace. How to fix this kind of crash problem. Thread 1 Crashed:: Dispatch queue: com.apple.root.background-qos 0 libsystem_kernel.dylib 0x7ff81b84922a __pthread_kill + 10 1 libsystem_pthread.dylib 0x7ff81b880f7b pthread_kill + 263 2 libsystem_c.dylib 0x7ff81b7caca5 abort + 123 3 libc++abi.dylib 0x7ff81b83b082 abort_message + 241 4 libc++abi.dylib 0x7ff81b82c23d demangling_terminate_handler() + 266 5 libobjc.A.dylib 0x7ff81b529023 _objc_terminate() + 96 6 libc++abi.dylib 0x7ff81b83a4a5 std::__terminate(void (*)()) + 8 7 libc++abi.dylib 0x7ff81b83a456 std::terminate() + 54 8 libdispatch.dylib 0x7ff81b701a58 _dispatch_client_callout + 28 9 libdispatch.dylib 0x7ff81b704500 _dispatch_continuation_pop + 463 10 libdispatch.dylib 0x7ff81b715dff _dispatch_source_invoke + 2184 11 libdispatch.dylib 0x7ff81b7116a2 _dispatch_root_queue_drain + 343 12 libdispatch.dylib 0x7ff81b711e4d _dispatch_worker_thread2 + 160 13 libsystem_pthread.dylib 0x7ff81b87dc9d _pthread_wqthread + 256 14 libsystem_pthread.dylib 0x7ff81b87cc67 start_wqthread + 15 This crash point is exactly same with this post. I do not throw C++ exception. https://developer.apple.com/forums/thread/725197
Posted
by Himadeus.
Last updated
.
Post marked as solved
8 Replies
2.6k Views
I see this warning when my app runs: Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions This is true; I know what is going on. I'd like this other thread to have a higher priority. But how do I set the "QOS class" for a thread? Searching developer.apple.com for QOS_CLASS_USER_INTERACTIVE doesn't find much. It seems that dispatch queues have priorities, but in this case I have a thread, not a dispatch queue. Any ideas?
Posted
by endecotp.
Last updated
.
Post marked as solved
2 Replies
568 Views
Below is some simple code that does nothing, saves nothing. Yet the memory usage keeps rising. Am I missing something or is this a bug? The code requires 6 core CPU minimum. ContentView.swift import SwiftUI import Combine struct ContentView: View { @EnvironmentObject var loopClass:LoopClass var body: some View { ProgressView(value: Float(loopClass.loop_count), total: Float(loopClass.max_loops) ).progressViewStyle(.circular).padding() Button("Run looper", action: { loopClass.loopFunc() } ) } } LoopClass.swift import Combine class LoopClass: ObservableObject { @Published var loop_count = 0 @Published var max_loops = 0 func loopFunc () { let loopSet = [ 1, 3, 5, 7, 11, 13 ] max_loops = Int(pow(Double(loopSet.count), 13.0)) print("max_loops = \(max_loops)") for loop13 in loopSet { DispatchQueue.global().async { for loop12 in loopSet { for loop11 in loopSet { for loop10 in loopSet { for loop9 in loopSet { for loop8 in loopSet { for loop17 in loopSet { for loop16 in loopSet { for loop5 in loopSet { for loop4 in loopSet { for loop3 in loopSet { for loop2 in loopSet { for loop1 in loopSet { DispatchQueue.main.async{ self.loop_count += 1 } } }}}}}}}}}}} } // DQ } // for loop13 } }
Posted Last updated
.
Post not yet marked as solved
0 Replies
1.2k Views
In What's New In Swift, a new DispatchSerialQueue-backed actor was introduced. We're able to call MainActor-annotated functions using DispatchQueue.main.async without errors or warnings. For example: @MainActor func randomFunc() { print("Hello World") } DispatchQueue.main.async { randomFunc() } However calling a globalActor-annotated function or a regular actor-isolated function backed by a DispatchSerialQueue, we get the warning Actor-isolated instance method 'randomFunc()' can not be referenced from a non-isolated context; this is an error in Swift 6. Code here: actor MyActor { private let queue: DispatchSerialQueue nonisolated var unownedExecutor: UnownedSerialExecutor { queue.asUnownedSerialExecutor() } init(queue: DispatchSerialQueue) { self.queue = queue } func randomFunc() { print("Hello World!") } } let queue = DispatchSerialQueue(label: "actorQueue") let actor = MyActor(queue: queue) queue.async { actor.randomFunc() // Warning here } Although it has a warning, the code still runs successfully and prints Hello World, but it would also do so from another DispatchQueue not used by the actor (this was tested in Version 15.0 beta (15A5160n) Playground). My question: Can we remove the warning resulting from calling an actor isolated function backed by DispatchSerialQueue A using A.async { }, if that's safe behavior? If it's not safe, why not?
Posted
by achouman.
Last updated
.