Is it possible for a Closure (Swift) to capture reference of the instance of the object that executes it?

0

I'm passing a closure to an object's property, and within the closure I'd need to reference the instance of the object that will execute the closure. Example:

 typealias validator : ()->Bool

      class Field : NSObject {
         var name     : String?
         var validate : validator?
     }

     var primeiroNome       = Field()
      primeiroNome.name     = "Pedro"
      primeiroNome.validate = { ()-Bool

       // self ou uma outra referencia a instancia de primeiroNome
       return self.name != "" ? true : false

     }

    primeiroNome.validate() // Retorna true ou false

The solution I'm using is to use a closure that gets an instance of type Field as parameter like this:

typealias validator : (_ instance : Field)->Bool

  class Field : NSObject {
     var name     : String?
     var validate : validator?  }

 var primeiroNome      = Field()  
 primeiroNome.name     = "Pedro"  
 primeiroNome.validate = { (instance)-Bool -> in

   // self ou uma outra referencia a instancia de primeiroNome    
   return instance.name != "" ? true : false

 }

 primeiroNome.validate(primeiroNome) // Retorna true ou false

The alternative I found works, but I would really like to be able to run the closure without having to pass the instance as a parameter.

    
asked by anonymous 21.11.2016 / 14:23

2 answers

1

No. Why?

Clousures are Reference Types . This means that when you declare a clousure to a variable, you are declaring its type, not its value. The content of this clousure will be the value of your variable.

Example:

var exemplo : () -> Bool = { return true }

We can read the above line like this:

  

"The 'example' variable is a clousure of type () -> Bool with a positive boolean value"

In order to "catch the instance reference of the object executing it", you will need to do this through instance of the clousure instance, p> strong tip strong tip : Use a capture list self to weak or unowned . This will prevent you from creating Strong Reference Cycles .

More about clousures :

Clousures Are Reference Types - The Swift Programming Language ( link ):

    
06.03.2017 / 21:14
1

It looks like the code you pasted is not complete. But from what you wrote you could do it.

class Field {
    var name: String?
    var validate: (() -> Bool)?
}

class MyClass {
    var field: Field {
        let myField = Field()
        myField.validate = { self.field.name != nil }
        return myField
    }

    func validateField(){
        field.validate?()
    }
}

MyClass().validateField()
    
11.01.2017 / 04:44