Skip to content

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
@firebase firebase locked and limited conversation to collaborators Dec 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants