Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

279
Views
¿Cómo se vuelve a llamar a didSet cuando se establece dentro a través de una función?

Por lo que sé y como se menciona en este hilo, si configuro un valor de propiedad en su observador didSet , no debería volver a activar el observador. Bien, entonces escribí un código como este:

 class B { var i = 0 { didSet { print("didSet called") self.i += 1 } } } var y = B() yi = 2 print(yi)

Este código imprime "didSet called" y 3 como salida como se esperaba. Pero hice un pequeño cambio en este código de la siguiente manera:

 class B { var i = 0 { didSet { print("didSet called") doit(val: self) } } func doit(val: B) { val.i += 1 } } var y = B() yi = 2 print(yi)

Pero ahora cae en un bucle infinito que imprime "didSet called" . ¿Por qué si establezco un valor para la variable dentro didSet pasándolo a través de un argumento de función, didSet nuevamente? Dado que el objeto pasado debe referirse al mismo objeto, no sé por qué sucede esto. Probé y si lo configuro a través de un cierre en didSet en lugar de una función normal, vuelve a un bucle infinito.

Actualización: es divertido que incluso esto desencadene un bucle infinito:

 class B { var i = 0 { didSet { print("called") doit() } } func doit() { self.i += 1 } }
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Después de consultar con Swift github y hacer preguntas sobre este problema, descubrí que este problema es más complejo de lo que parece. Pero hay una regla específica sobre este problema:

El observador didSet no se activará solo si el acceso a la propiedad dentro de su propio observador didSet se puede realizar a través del acceso directo a la memoria.

El problema es que es un poco ambiguo cuándo el acceso a la propiedad será directo (a menos que probablemente sea un desarrollador de Swift). Una característica importante que tiene un efecto en mi pregunta es esta:

El método de instancia de clase nunca accede directamente a las propiedades de clase.

Esta cita muestra un problema con mi código, aunque puedo argumentar que cuando un miembro de la instancia debería poder acceder a la propiedad directamente siempre que lo llame en didSet observe. Cuando tengo un código como este:

 class B { var i = 0 { didSet { print("called") doit() } } func doit() { self.i += 1 } }

La función doit() no puede acceder a i directamente, lo que activa didSet nuevamente y causa un bucle infinito.

Ahora, ¿cuál es la solución?

Puede usar inout para pasar propiedades de su propio didSet a una función de instancia sin activar didSet . Algo como esto:

 class B { var i = 0 { didSet { print("called") doit(&i) } } func doit(_ i: inout Int) { i += 1 } }

Y una última cosa. A partir de Swift 5 , las condiciones para seleccionar el acceso directo a la memoria para las propiedades dentro de su propio didSet serán más restringidas. Según github, las únicas condiciones que utilizarán el acceso directo a la memoria son las siguientes:

 Within a variable's own didSet/willSet specifier, access its storage directly if either: 1) It's a 'plain variable' (ie a variable that's not a member). 2) It's an access to the member on the implicit 'self' declaration. If it's a member access on some other base, we want to call the setter as we might be accessing the member on a *different* instance.

Esto significa que los códigos como los siguientes activarán un bucle infinito mientras que ahora no lo hace:

 class B { var i = 0 { didSet { print("called") var s = self si += 1 } } }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!