Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

281
Visualizações
How is didSet called again when setting inside through a function?

As far as I know and as mentioned in this thread, if I set a property value in its didSet observer, it should not trigger the observer again. OK, then I wrote a piece of code like this:

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

var y = B()
y.i = 2
print(y.i)

This code prints "didSet called" and 3 as output as expected. But I made a small change to this code as follows:

class B {
    var i = 0 {
        didSet {
            print("didSet called")
            doit(val: self)
        }
    }

    func doit(val: B) {
        val.i += 1
    }
}

var y = B()
y.i = 2
print(y.i)

But now it falls into an infinite loop printing "didSet called". Why if I set a value to the variable inside didSet via passing it through a function argument, does it trigger didSet again? Since the passed object should refer to the same object, I don't know why this happens. I tested and if I set it via a closure in didSet rather than a normal function it goes to an infinite loop again.

Update: It is funny that even this triggers an infinite loop:

class B {
    var i = 0 {
        didSet {
            print("called")            
            doit()
        }
    }

    func doit() {
        self.i += 1
    }
}
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

After checking with Swift github and asking questions about this problem, I find out that this problem is more complex as it seems. But there is a specific rule about this problem:

didSet observer will not trigger only if access to property within its own didSet observer can be done through direct memory access.

Problem is that it is a little ambiguous when access to property will be direct(unless probably if you are developer of Swift). An important feature that has an effect on my question is this:

Class instance method never access class properties directly.

This quote shows problem with my code, even though I can argue that when an instance member should be able to access property directly whenever you call it in didSet observe. When I have a code like this:

class B {
    var i = 0 {
        didSet {
            print("called")            
            doit()
        }
    }

    func doit() {
        self.i += 1
    }
}

doit() function cannot access i directly which triggers didSet again causing infinite loop.

Now what is the workaround?

You can use inout for passing properties from its own didSet to a instance function without triggering didSet. Something like this:

class B {
    var i = 0 {
        didSet {
            print("called")            
            doit(&i)
        }
    }

    func doit(_ i: inout Int) {
        i += 1
    }
}

And one last thing. Starting Swift 5, conditions for selecting direct memory access for properties within its own didSet will become more restricted. Based on github, only conditions that will use direct memory access is are the following:

 Within a variable's own didSet/willSet specifier, access its storage
 directly if either:
 1) It's a 'plain variable' (i.e 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.

This means codes like following will trigger infinite loop while it does not right now:

class B {
    var i = 0 {
        didSet {
            print("called")            
            var s = self
            s.i += 1
        }
    }
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda