初始化需要“self”作为参数的 Swift 属性
Posted
技术标签:
【中文标题】初始化需要“self”作为参数的 Swift 属性【英文标题】:Initializing Swift properties that require "self" as an argument 【发布时间】:2014-08-05 22:15:45 【问题描述】:我有一个 Swift 类,我希望它看起来像这样:
class UpdateManager
let timer: NSTimer
init()
timer = NSTimer(timeInterval: 600, target: self, selector: "check", userInfo: nil, repeats: true)
func check()
// Do some stuff
但是,Swift 不喜欢我将 self
传递给 NSTimer
初始化程序的事实。我在这里打破了一些模式吗?应该如何完成这样的初始化?
【问题讨论】:
【参考方案1】:您已找到Implicitly Unwrapped Optional 的主要用例。
在初始化timer
之前,您需要从init
访问self
。
否则,timer
应该永远为零,因此您不必在init
之外检查它。
所以,你应该声明let timer: NSTimer!
。
【讨论】:
这很棒。当您回答时,我已经知道如何将隐式解包选项与var
一起使用,但不知道它们与let
兼容。谢谢!
这是一个很好的问题,坦率地说,我很惊讶它还没有被问到!很高兴看到 IUO 被用于其真正目的,而不是在导入 Obj-C API 时自动撒在各处......【参考方案2】:
Swift 2 可能改变了工作方式。我正在使用如下代码:
@objc class Test : NSObject
var timer : NSTimer!
init text()
super.init()
timer = NSTimer(timeInterval: 1.0, target: self, selector: "timerFired:", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
需要@objc 声明和 NSObject 子类。 另外 timer 需要是一个 var,而不是 let。
【讨论】:
【参考方案3】:除了隐式展开的可选选项之外,我发现要使代码正常工作,我需要继承 NSObject 并将计时器添加到当前运行循环中。
class UpdateManager:NSObject
let timer: NSTimer!
override init()
super.init()
timer = NSTimer(timeInterval: 600, target: self, selector: "check", userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
func check()
// Do some stuff
基于 cmets 更新代码 - 感谢 jtbandes 和 Caroline
class UpdateManager
let timer: NSTimer!
init()
timer = NSTimer.scheduledTimerWithTimeInterval(600,
target: self,
selector: "check",
userInfo: nil,
repeats: true)
@objc func check()
// Do some stuff
【讨论】:
您可能想改用NSTimer.scheduledTimerWithTimeInterval(_:target:selector:userInfo:repeats:)
。
这消除了将计时器添加到运行循环的需要,但如果 NSObject 没有被子类化,则应用程序崩溃并显示以下消息:“不实现 methodSignatureForSelector: -- 前面的麻烦”
你可以像@objc func check ()
一样将@objc
属性添加到函数中,而不是继承NSObject
感谢@Caroline,它有效,我现在在文档中看到它的详细说明:“当您使用 Objective-C 类时,此属性 [@objc
] 也很有用使用选择器来实现目标动作设计模式——例如,NSTimer 或 UIButton。”值得一提的是,使用 dynamic 关键字也可以阻止应用程序崩溃,尽管我们应该使用 @objc
。以上是关于初始化需要“self”作为参数的 Swift 属性的主要内容,如果未能解决你的问题,请参考以下文章