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

475
Vistas
What is the reason behind objc_sync_enter doesn't work well with struct, but works well with class?

I have the following demo code.

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)")
            }
        }
    }
}

Whenever I execute click, I would get the following crash

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

It isn't clear why the crash happen. My raw guess is, under struct, objc_sync_enter(self) doesn't work as expected. 2 threads accessing Set simultaneously will cause such an issue.


If I change the struct to class, everything just work fine.

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
    }
}

May I know what is the reason behind? Why the above objc_sync_enter works well in class, but not in 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