ios - Swift 选择器和闭包讨论

标签 ios objective-c swift closures

我搜索了很多,但没有找到任何真正有助于解决我的问题的东西......

我正在尝试从头开始构建一个简单的 UIControl,例如 UIButton。由于特殊原因,它不能是 UIControl 的子类。

我需要这个控件来做这样的事情:

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

问题是触摸按钮时执行此选择器的方法的实现需要“performSelector:”方法。

Swift 没有“performSelector:”。所以我教它可以使用闭包来实现。

我不知道如何在闭包中捕获我想要修改的对象。 而且我不确定我将如何处理引用循环和其他类似的事情。

我什至不知道我是否在正确的道路上取得成功。我相信你们能让我走上正轨!

我来自巴西,抱歉我的英语不好!谢谢! :D

这是到目前为止的内容......

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

在此代码中,self 引用了 control 作为其字段,control 引用了 self 通过 addClosureFor 添加的闭包。这形成了一个循环引用,因此循环中的这些对象永远不会被释放。

闭包捕获列表有助于解决这个问题。

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 被弱捕获,因此从 selfcontrol 只形成一个单向引用. 请注意,现在在闭包中,无法保证对 self 的访问,因为 self 是弱引用的。您必须将 self 视为可选值。

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

关于ios - Swift 选择器和闭包讨论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28778010/

相关文章:

ios - UIScrollview 分页中的 UITextview

iphone - 带按钮的自定义 UINavigationController

objective-c - 在 SpriteKit 中循环背景音乐

objective-c - 使用带有叠加功能的 iPad/iPhone 上的相机

ios - 如何在 Realm swift 中使用 distinctUnionOfObjects

ios - 绘制(_矩形: CGRect) not getting called in custom view

objective-c - ASIHTTPRequestTester : Asynchronous not working

ios - 覆盖或扩展 UIColor 以支持某些协议(protocol)

ios - 如何使用选择器将每个用户的多个图像存储到核心数据中?

swift - 在 swift 4 或更高版本上创建触摸测试应用程序