简体   繁体   English

Swift选择器和闭包讨论

[英]Swift Selectors and Closures Discussion

I searched a lot and haven't found anything that really helped to solve my problem... 我搜索了很多东西,却没有发现任何真正有助于解决我的问题的东西...

I'm trying to build a simple UIControl from scratch, like a UIButton. 我试图从头开始构建一个简单的UIControl,如UIButton。 It can't be subclass of UIControl for particular reasons. 由于特定原因,它不能成为UIControl的子类。

I need this control to do something like this: 我需要此控件来执行以下操作:

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

The problem is that the implementation of the method that execute this selector when the button is touched needs the "performSelector:" method. 问题在于,在触摸按钮时执行此选择器的方法的实现需要“ performSelector:”方法。

Swift doesn't have a "performSelector:". Swift没有“ performSelector:”。 So I taught it could be implemented using closures. 所以我教了它可以使用闭包来实现。

I couldn't figure out how to capture the objects I want to modify inside the closure. 我不知道如何捕获要在闭包内部修改的对象。 And I'm not sure how I would deal with reference cycles and other things like that. 而且我不确定如何处理参考周期和其他类似问题。

I don't even know if I am on the right path to succeed this. 我什至不知道我是否走上了成功的道路。 I'm sure you guys can put me on the right track! 我相信你们可以让我走上正确的轨道!

I'm from Brazil, sorry for my poor English! 我来自巴西,对不起我的英语不好! Thanks! 谢谢! :D :d

Here is what a 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?"
            })
       }
  }

In your case at the moment, it seems that no cyclic-reference is formed. 在您目前的情况下,似乎没有形成循环引用。 But it's possible to accidentally be formed in the future. 但是将来可能会偶然形成。 Like the followings 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, self has a reference to the control as its field and the control has a reference to self through the closure added by addClosureFor . 在此代码中, self引用了control作为其字段, control通过addClosureFor添加的闭包引用了self This forms a cyclic reference so these objects in the cycle are never released. 这形成了循环引用,因此循环中的这些对象从不释放。

closure capture list helps this issue. 关闭捕获列表可以解决此问题。

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
}

In the block in this code above, self is weakly captured so that an only one unidirectional reference is formed from self to the control . 在上面这段代码的代码块中,弱捕获了self因此从selfcontrol仅形成一个单向参考。 Note that, now in the closure, the access to self isn't assured because self is weakly-referenced. 需要注意的是,现在的罩盖,以访问self不放心,因为self是弱引用。 You have to consider self an optional value. 您必须将self视为可选值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM