Swift中的dispatch_once示例 [英] Example of dispatch_once in Swift

查看:341
本文介绍了Swift中的dispatch_once示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一个例子说明如何在Swift中使用 dispatch_once ? (最好来自苹果。)



注意:在这种情况下,我不使用它为单身人士;我想要运行任意代码一次。



更新:我主要感兴趣的惯例推荐在一个实例方法中使用,但是在类方法,函数和全局上下文中的使用将有助于完整性。

解决方案

dispatch_once_t 是类型别名( Int )。标头文档:

  / *! 
* @typedef dispatch_once_t
*
* @abstract
*用于dispatch_once()的谓词。它必须初始化为零。
*注意:静态和全局变量默认为零。
* /
typealias dispatch_once_t = Int

c $ c> dispatch_once 文档:


谓词必须指向存储在全局或静态的变量
范围。未定义使用带有自动或动态
存储(包括Objective-C实例变量)的谓词的结果。


令牌变量必须存储在全局/静态作用域中,并且必须初始化为零,这将导致此代码:

  import Foundation 

var token:dispatch_once_t = 0
dispatch_once(& token){() - >无效
print(Called once)
}

如果省略 = 0 令牌初始化),因为编译器产生错误变量地址'在它被初始化之前被采用,尽管事实上静态和全局默认为零。在Xcode 7B2中测试。






更多基于评论的示例。如果你在 class 方法中有几种可能性。



你不能在方法中声明静态属性编译器产生静态属性只能在类型错误上声明。这不起作用:

  class func doItOnce(){
static var token:dispatch_once_t = 0
...
}

必须在类型上声明。这是在Swift 1.2(Xcode 6.3 IIRC)中引入的。


static方法和属性现在允许在类中$ bclass final的别名)。现在允许在类中声明静态存储的
属性,它们具有全局存储,并且在第一次访问时(例如全局变量)初始化
。现在的协议
将类型需求声明为static需求,而不是
声明为类需求。 (17198298)


那么,如果我们不喜欢全局变量,我们该怎么办?



类型上的静态变量

  class MyClass {
private static var token:dispatch_once_t = 0

class func doItOnce(){
dispatch_once(& token){
print(Do it once)
}
}
}

>



不喜欢yur类的静态属性?想要在你的方法吗?像这样将它包装在struct中:

  class func doItOnce(){
struct Tokens {static var token:dispatch_once_t = 0}
dispatch_once(& Tokens.token){
print(Do it once)
}
}
pre>

其实我不知道任何苹果的建议,最佳实践,...如何做 dispatch_once 。只需使用任何你最喜欢的,感觉很好,只满足条件全局/静态范围。


Is there an example of how dispatch_once should be used in Swift? (Preferably one from Apple.)

Note: In this case, I'm not using it for a singleton; I want to run arbitrary code exactly once.

Update: I'm mainly interested in the convention recommended when using this in an instance method, but usage in a class method, function, and in the global context would be useful for completeness sake.

解决方案

dispatch_once_t is type alias (Int). Header documentation:

/*!
 * @typedef dispatch_once_t
 *
 * @abstract
 * A predicate for use with dispatch_once(). It must be initialized to zero.
 * Note: static and global variables default to zero.
 */
typealias dispatch_once_t = Int

And here's the quote from dispatch_once documentation:

The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.

Token variable must be stored in global / static scope and must be initialized to zero, which leads to this code:

import Foundation

var token: dispatch_once_t = 0
dispatch_once(&token) { () -> Void in
  print("Called once")
}

It doesn't work if you omit = 0 (token initialization), because compiler yields error Address of variable 'token' taken before it is initialized despite the fact that statics and globals default to zero. Tested in Xcode 7B2.


More examples based on comment. If you're inside class method you have several possibilities.

You can't declare static property inside method otherwise compiler yields Static properties may only be declared on a type error. This doesn't work:

class func doItOnce() {
  static var token: dispatch_once_t = 0
  ...
}

Must be declared on a type. This was introduced in Swift 1.2 (Xcode 6.3 IIRC).

"static" methods and properties are now allowed in classes (as an alias for "class final"). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as "static" requirements instead of declaring them as "class" requirements. (17198298)

So, what we can do if we don't like globals?

Static variable on a type

class MyClass {
  private static var token: dispatch_once_t = 0

  class func doItOnce() {
    dispatch_once(&token) {
      print("Do it once")
    }
  }
}

Static in a method wrapped in struct

Don't like static property on yur class? Would like to have it in your method? Wrap it in struct like this:

class func doItOnce() {
  struct Tokens { static var token: dispatch_once_t = 0 }
  dispatch_once(&Tokens.token) {
    print("Do it once")
  }
}

Actually I'm not aware of any Apple recommendation, best practice, ... how to do it for dispatch_once. Simply use whatever you like most, feels good to you and just meet criteria global / static scope.

这篇关于Swift中的dispatch_once示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆