Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

477
Vistas
¿Cuál es la razón por la que objc_sync_enter no funciona bien con struct, pero funciona bien con class?

Tengo el siguiente código de demostración.

 struct IdGenerator { private var lastId: Int64 private var set: Set<Int64> = [] init() { self.lastId = 0 } mutating func nextId() -> Int64 { objc_sync_enter(self) defer { objc_sync_exit(self) } repeat { lastId = lastId + 1 } while set.contains(lastId) precondition(lastId > 0) let (inserted, _) = set.insert(lastId) precondition(inserted) return lastId } } var idGenerator = IdGenerator() class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } @IBAction func click(_ sender: Any) { DispatchQueue.global(qos: .userInitiated).async { for i in 1...10000 { let id = idGenerator.nextId() print("i : \(id)") } } DispatchQueue.global(qos: .userInitiated).async { for j in 1...10000 { let id = idGenerator.nextId() print("j : \(id)") } } } }

Cada vez que ejecuto click , obtendría el siguiente bloqueo

 Thread 5 Queue : com.apple.root.user-initiated-qos (concurrent) #0 0x000000018f58b434 in _NativeSet.insertNew(_:at:isUnique:) () #1 0x000000018f598d10 in Set._Variant.insert(_:) () #2 0x00000001001fe31c in IdGenerator.nextId() at /Users/yccheok/Desktop/xxxx/xxxx/ViewController.swift:30 #3 0x00000001001fed8c in closure #2 in ViewController.click(_:) at /Users/yccheok/Desktop/xxxx/xxxx/ViewController.swift:56

No está claro por qué ocurrió el accidente. Mi conjetura es, bajo struct , objc_sync_enter(self) no funciona como se esperaba. 2 subprocesos que acceden a Set simultáneamente causarán tal problema.


Si cambio la struct a class , todo funciona bien.

 class IdGenerator { private var lastId: Int64 private var set: Set<Int64> = [] init() { self.lastId = 0 } func nextId() -> Int64 { objc_sync_enter(self) defer { objc_sync_exit(self) } repeat { lastId = lastId + 1 } while set.contains(lastId) precondition(lastId > 0) let (inserted, _) = set.insert(lastId) precondition(inserted) return lastId } }

¿Puedo saber cuál es la razón detrás? ¿Por qué el objc_sync_enter anterior funciona bien en class , pero no en struct ?

over 4 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda