首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift - scheduledTimerWithTimeInterval - NSInvocation

Swift - scheduledTimerWithTimeInterval - NSInvocation
EN

Stack Overflow用户
提问于 2016-07-05 02:45:58
回答 5查看 5K关注 0票数 5

我想在将来安排一个函数调用。我在用斯威夫特。

我想回调一个私有的方法,并返回一个承诺(从PromiseKit)

所有我见过的例子

代码语言:javascript
复制
NSTimer.scheduledTimerWithTimeInterval(ti: NSTimeInterval, target: AnyObject, selector: Selector, userInfo: AnyObject?, repeats: Bool)

很好。我试过了

代码语言:javascript
复制
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "connect", userInfo: nil, repeats: false)

这对No method declared with Objective-C selector 'connect'来说是失败的。

目标C在这里做什么?

无论如何,建议我在我的方法@objc前面添加connect。很好。我不能因为显然是Method cannot be marked @objc because its result type cannot be represented in Objective-C

如果我想用目标C,我不会写Swift.

还有另一个scheduledTimerWithTimeInterval

代码语言:javascript
复制
NSTimer.scheduledTimerWithTimeInterval(ti: NSTimeInterval, invocation: NSInvocation, repeats: Bool)

但据我所知,NSInvocation并不是一个迅速的东西.

因此,我最终创建了一个包装器,它只会调用connect并返回目标C能够理解的Void。很管用,但感觉很蠢。有更好的方法吗?

额外好处:为什么javascript可以像setTimeout(this.connect, 1)和Swift那样简单地做到我所能找到的方式呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-11-12 06:40:46

从iOS 10和Swift 3开始,可以使用带有块闭包的(NS)定时器,从而避免在计时器触发时调用目标-C选择器:

代码语言:javascript
复制
    if #available(iOS 10.0, *) {
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { (Timer) in
            self.connect() // per the OP's example
        })
    }

除了避免使用@objc装饰符之外,使用此技术还可以调用包含非目标C兼容的参数类型(如枚举和选项)的方法。

Re:setTimeout(this.connect, 1)来自Javascript,如果您不需要取消它,Swift 3中的一个更直接的类比可能是:

代码语言:javascript
复制
DispatchQueue.Main.asyncAfter(deadline: .now() + 1.0, execute { self.connect() })

这非常接近,因为您实际上可以选择在哪个线程上运行;-)

票数 4
EN

Stack Overflow用户

发布于 2016-07-05 02:57:20

目标C在这里做什么?

之所以需要Objective,是因为它在运行时动态地绑定“调用”(在Objective中没有调用),而Swift不能这样做。Swift无法在计时器类中“调用”一个在NSTimer编译时不知道的“函数”。

顺便说一句:NSTimer使用NSInvocation (或类似的不可滑动技术)来执行“调用”。因此,NSTimer的使用并不是更灵活,但是为了让Swift开发人员感觉更好,对后期绑定的需求变得更加模糊。

如果我想用目标C,我不会写Swift.

即使您的代码完全是用Swift编写的,它也从Objective的后期绑定中获得了很多好处。Cocoa的许多核心技术是无法用Swift编写的,包括响应链、撤消管理器、核心数据、动画…(另一方面,你可以定义一个操作符,什么是软件工程的一大进步,并描述了整个故事。)

票数 1
EN

Stack Overflow用户

发布于 2016-07-05 02:49:46

请记住,SWIFT2.2/ Xcode 7.3有一种使用选择器的新方法:Selector("funcName")已更改为#selector(ClassName.funcName)

你应该使用#selector

代码语言:javascript
复制
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(YourClass.connect), userInfo: nil, repeats: false)

或者Selector("connect"),但是要记住,您将收到警告:

代码语言:javascript
复制
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("connect"), userInfo: nil, repeats: false)

还可以查看,以了解如何使用Selector()

更多参考方法这里的目标-C选择器的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38194513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档