Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Config] Prefer NSLock over objc_sync_enter for synchronizing value types #14041

Merged
merged 1 commit into from
Nov 6, 2024

Conversation

ncooke3
Copy link
Member

@ncooke3 ncooke3 commented Nov 6, 2024

objc_sync_enter shouldn't be used on value types ([String: UserDefaults]) because a struct's address is not stable (https://stackoverflow.com/a/70897304/9331576, https://straypixels.net/swift-dictionary-locking/).

I could demonstrate this in a playground using a simplified version of the class:

import Foundation

class UserDefaultsManager: NSObject {
  nonisolated(unsafe) private static var sharedInstanceMap: [String: UserDefaults] = [:]
  
  /// Returns the shared user defaults instance for the given bundle identifier.
  ///
  /// - Parameter bundleIdentifier: The bundle identifier of the app.
  /// - Returns: The shared user defaults instance.
  static func setValue(_ value: UserDefaults, key: String) -> UserDefaults {
    print("enter: \(ObjectIdentifier(Self.sharedInstanceMap as AnyObject))")
    objc_sync_enter(sharedInstanceMap)
    defer {
      print(" exit: \(ObjectIdentifier(Self.sharedInstanceMap as AnyObject))")
      objc_sync_exit(sharedInstanceMap)
    }
    sharedInstanceMap[key] = value
    return value
  }
}

UserDefaultsManager.setValue(.standard, key: "standard_1")
// enter: ObjectIdentifier(0x00000001ec706cf0)
//  exit: ObjectIdentifier(0x0000600000c32640)

UserDefaultsManager.setValue(.standard, key: "standard_2")
// enter: ObjectIdentifier(0x0000600000c32610)
//  exit: ObjectIdentifier(0x0000600000c32580)

Interesting reads on synchronization performance:

#no-changelog

@ncooke3 ncooke3 merged commit 99e737f into rc-swift Nov 6, 2024
61 of 63 checks passed
@ncooke3 ncooke3 deleted the nc/rc-swift-2 branch November 6, 2024 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants