Concurrency

RSS for tag

Concurrency is the notion of multiple things happening at the same time.

Posts under Concurrency tag

84 Posts

Post

Replies

Boosts

Views

Activity

Crash when Mutating Array of Tuples with String Property from Multiple Threads
Hi Apple Developer Community, I'm facing a crash when updating an array of tuples from both a background thread and the main thread simultaneously. Here's a simplified version of the code in a macOS app using AppKit: class ViewController: NSViewController { var mainthreadButton = NSButton(title: "test", target: self, action: nil) var numbers = Array(repeating: (dim: Int, key: String)(0, "default"), count: 1000) override func viewDidLoad() { super.viewDidLoad() view.addSubview(mainthreadButton) mainthreadButton.translatesAutoresizingMaskIntoConstraints = false mainthreadButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true mainthreadButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true mainthreadButton.widthAnchor.constraint(equalToConstant: 100).isActive = true mainthreadButton.heightAnchor.constraint(equalToConstant: 100).isActive = true mainthreadButton.target = self mainthreadButton.action = #selector(arraytest(_:)) } @objc func arraytest(_ sender: NSButton) { print("array update started") // Background update DispatchQueue.global().async { for i in 0..<1000 { self.numbers[i].dim = i } } // Main thread update var sum = 0 for i in 0..<1000 { numbers[i].dim = i + 1 sum += numbers[i].dim print("test \(sum)") } mainthreadButton.title = "test = \(sum)" } } This results in a crash with the following message: malloc: double free for ptr 0x136040c00 malloc: *** set a breakpoint in malloc_error_break to debug What's interesting: This crash only happens when the tuple contains a String ((dim: Int, key: String)) If I change the tuple type to use two Int values ((dim: Int, key: Int)), the crash does not occur My Questions: Why does mutating an array of tuples containing a String crash when accessed from multiple threads? Why is the crash avoided when the tuple contains only primitive types like Int? Is there an underlying memory management issue with value types containing reference types like String? Any explanation about this behavior and best practices for thread-safe mutation of such arrays would be much appreciated. Thanks in advance!
1
0
296
Apr ’25
Working with Input/Output stream with Swift 6 and concurrency framework
Hello, I am developing an application which is communicating with external device using BLE and L2CAP. I wonder what are the best practices of using Input & Output streams that are established with L2CAP connection when working with Swift 6 concurrency model. I've been trying to find some examples and hints for some time now but unfortunately there isn't much available. One useful thread I've found is: https://developer.apple.com/forums/thread/756281 but it does not offer much insight into using eg. actor model with streams. I wonder if something has changed in this regards? Also, are there any plans to migrate eg. CoreBluetooth stack to new swift 6 concurrency ?
2
0
170
Apr ’25
Return the results of a Spotlight query synchronously from a Swift function
How can I return the results of a Spotlight query synchronously from a Swift function? I want to return a [String] that contains the items that match the query, one item per array element. I specifically want to find all data for Spotlight items in the /Applications folder that have a kMDItemAppStoreAdamID (if there is a better predicate than kMDItemAppStoreAdamID > 0, please let me know). The following should be the correct query: let query = NSMetadataQuery() query.predicate = NSPredicate(format: "kMDItemAppStoreAdamID > 0") query.searchScopes = ["/Applications"] I would like to do this for code that can run on macOS 10.13+, which precludes using Swift Concurrency. My project already uses the latest PromiseKit, so I assume that the solution should use that. A bonus solution using Swift Concurrency wouldn't hurt as I will probably switch over sometime in the future, but won't be able to switch soon. I have written code that can retrieve the Spotlight data as the [String], but I don't know how to return it synchronously from a function; whatever I tried, the query hangs, presumably because I've called various run loop functions at the wrong places. In case it matters, the app is a macOS command-line app using Swift 5.7 & Swift Argument Parser 1.5.0. The Spotlight data will be output only as text to stdout & stderr, not to any Apple UI elements.
1
0
201
Apr ’25
Help Understanding Concurrency Error with Protocol Listener and Actor
Hi all, I'm running into a Swift Concurrency issue and would appreciate some help understanding what's going on. I have a protocol and an actor set up like this: protocol PersistenceListener: AnyObject { func persistenceDidUpdate(key: String, newValue: Any?) } actor Persistence { func addListener(_ listener: PersistenceListener) { listeners.add(listener) } /// Removes a listener. func removeListener(_ listener: PersistenceListener) { listeners.remove(listener) } // MARK: - Private Properties private var listeners = NSHashTable<AnyObject>.weakObjects() // MARK: - Private Methods /// Notifies all registered listeners on the main actor. private func notifyListeners(key: String, value: Any?) async { let currentListeners = listeners.allObjects.compactMap { $0 as? PersistenceListener } for listener in currentListeners { await MainActor.run { listener.persistenceDidUpdate(key: key, newValue: value) } } } } When I compile this code, I get a concurrency error: "Sending 'listener' risks causing data races"
4
0
169
Apr ’25
Crash when Mutating Array of Tuples with String Property from Multiple Threads
Hi Apple Developer Community, I'm facing a crash when updating an array of tuples from both a background thread and the main thread simultaneously. Here's a simplified version of the code in a macOS app using AppKit: class ViewController: NSViewController { var mainthreadButton = NSButton(title: "test", target: self, action: nil) var numbers = Array(repeating: (dim: Int, key: String)(0, "default"), count: 1000) override func viewDidLoad() { super.viewDidLoad() view.addSubview(mainthreadButton) mainthreadButton.translatesAutoresizingMaskIntoConstraints = false mainthreadButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true mainthreadButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true mainthreadButton.widthAnchor.constraint(equalToConstant: 100).isActive = true mainthreadButton.heightAnchor.constraint(equalToConstant: 100).isActive = true mainthreadButton.target = self mainthreadButton.action = #selector(arraytest(_:)) } @objc func arraytest(_ sender: NSButton) { print("array update started") // Background update DispatchQueue.global().async { for i in 0..&lt;1000 { self.numbers[i].dim = i } } // Main thread update var sum = 0 for i in 0..&lt;1000 { numbers[i].dim = i + 1 sum += numbers[i].dim print("test \(sum)") } mainthreadButton.title = "test = \(sum)" } } This results in a crash with the following message: malloc: double free for ptr 0x136040c00 malloc: *** set a breakpoint in malloc_error_break to debug What's interesting: This crash only happens when the tuple contains a String ((dim: Int, key: String)) If I change the tuple type to use two Int values ((dim: Int, key: Int)), the crash does not occur My Questions: Why does mutating an array of tuples containing a String crash when accessed from multiple threads? Why is the crash avoided when the tuple contains only primitive types like Int? Is there an underlying memory management issue with value types containing reference types like String? Any explanation about this behavior and best practices for thread-safe mutation of such arrays would be much appreciated. Thanks in advance!
Replies
1
Boosts
0
Views
296
Activity
Apr ’25
Working with Input/Output stream with Swift 6 and concurrency framework
Hello, I am developing an application which is communicating with external device using BLE and L2CAP. I wonder what are the best practices of using Input & Output streams that are established with L2CAP connection when working with Swift 6 concurrency model. I've been trying to find some examples and hints for some time now but unfortunately there isn't much available. One useful thread I've found is: https://developer.apple.com/forums/thread/756281 but it does not offer much insight into using eg. actor model with streams. I wonder if something has changed in this regards? Also, are there any plans to migrate eg. CoreBluetooth stack to new swift 6 concurrency ?
Replies
2
Boosts
0
Views
170
Activity
Apr ’25
Return the results of a Spotlight query synchronously from a Swift function
How can I return the results of a Spotlight query synchronously from a Swift function? I want to return a [String] that contains the items that match the query, one item per array element. I specifically want to find all data for Spotlight items in the /Applications folder that have a kMDItemAppStoreAdamID (if there is a better predicate than kMDItemAppStoreAdamID > 0, please let me know). The following should be the correct query: let query = NSMetadataQuery() query.predicate = NSPredicate(format: "kMDItemAppStoreAdamID > 0") query.searchScopes = ["/Applications"] I would like to do this for code that can run on macOS 10.13+, which precludes using Swift Concurrency. My project already uses the latest PromiseKit, so I assume that the solution should use that. A bonus solution using Swift Concurrency wouldn't hurt as I will probably switch over sometime in the future, but won't be able to switch soon. I have written code that can retrieve the Spotlight data as the [String], but I don't know how to return it synchronously from a function; whatever I tried, the query hangs, presumably because I've called various run loop functions at the wrong places. In case it matters, the app is a macOS command-line app using Swift 5.7 & Swift Argument Parser 1.5.0. The Spotlight data will be output only as text to stdout & stderr, not to any Apple UI elements.
Replies
1
Boosts
0
Views
201
Activity
Apr ’25
Help Understanding Concurrency Error with Protocol Listener and Actor
Hi all, I'm running into a Swift Concurrency issue and would appreciate some help understanding what's going on. I have a protocol and an actor set up like this: protocol PersistenceListener: AnyObject { func persistenceDidUpdate(key: String, newValue: Any?) } actor Persistence { func addListener(_ listener: PersistenceListener) { listeners.add(listener) } /// Removes a listener. func removeListener(_ listener: PersistenceListener) { listeners.remove(listener) } // MARK: - Private Properties private var listeners = NSHashTable<AnyObject>.weakObjects() // MARK: - Private Methods /// Notifies all registered listeners on the main actor. private func notifyListeners(key: String, value: Any?) async { let currentListeners = listeners.allObjects.compactMap { $0 as? PersistenceListener } for listener in currentListeners { await MainActor.run { listener.persistenceDidUpdate(key: key, newValue: value) } } } } When I compile this code, I get a concurrency error: "Sending 'listener' risks causing data races"
Replies
4
Boosts
0
Views
169
Activity
Apr ’25