Swift Selectors and Closures Discussion

I searched a lot and did not find anything that really helped solve my problem ...

I am trying to create a simple UIControl from scratch, like UIButton. It cannot be a subclass of UIControl for certain reasons.

I need this control to do something like this:

myControl.addTarget(target: AnyObject?, action: Selector, forControlEvents: UIControlEvents)

The problem is that to implement the method that executes this selector when the button is touched, the "make a choice:" method is needed.

Swift does not have a "performSelector:". Therefore, I taught him how to implement it using closures.

I could not figure out how to capture the objects that I want to change inside the closure. And I'm not sure how I will do reference cycles and other things like this.

I don’t even know if I am on the right track. I'm sure you guys can put me on the right track!

I am from Brazil, I apologize for my poor Englishman! Thank you !: D

Here is what you have so far ...

struct ClosureForEvent {
    var closure:(control:MyControl!)->()
    var event:UIControlEvents 
}

class MyControl {
     private var closures:[ClosureForEvent]?

     init() {}

     func addClosureFor(event:UIControlEvents, closure:(control:MyControl!)->()) {

          if closures == nil {
              closures = [ClosureForEvent(closure: closure, event: event)]
          }
          else {
              closures!.append(ClosureForEvent(closure: closure, event: event))
          }
      }


      func executeClosuresOf(event:UIControlEvents) {
          if closures != nil {
              for closure in closures! {
                  if closure.event == event {
                      closure.closure(control: control)
                  }
              }
          }
      }
  }

  class Test {
       var testProperty = "Default String"

       init() {
            let control = MyControl()
            control.addClosureFor(UIControlEvents.TouchUpInside, closure: { (control) -> () in
            self.testProperty = "This is making a reference cycle?"
            })
       }
  }
+1
source share
1 answer

In your case, at the moment it seems that the circular link is not being created. But in the future it can be accidentally formed. As for the instance.

// In the `Test` class.
let control = MyControl()
init() {
    control.addClosureFor(UIControlEvents.TouchUpInside, closure: { (control) -> () in
        self.testProperty = "This is making a reference cycle?"
    })
}

In this code it selfhas a link to controlas its field, and controlhas a link to selfthrough the closure added addClosureFor. This creates a circular reference, so these objects in the loop are never released.

A close capture list helps solve this problem.

control.addClosureFor(UIControlEvents.TouchUpInside) { [weak self] /* <-- */ control -> () in
    // Here, `self` is visible as `Optional<Test>` so the `?` operator is required.
    self?.testProperty = "This is making a reference cycle?"
    return
}

self , self control. , self , self . self .

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

+1

Source: https://habr.com/ru/post/1624555/


All Articles