swift - Swift 中 dispatch_once 的例子

标签 swift cocoa swift2

有没有在 Swift 中应该如何使用 dispatch_once 的例子? (最好是 Apple 的。)

注意:在本例中,我是 not using it for a singleton ;我想只运行一次任意代码。

更新:我主要对在实例方法中使用 this 时推荐的约定感兴趣,但是为了完整性起见,在类方法、函数和全局上下文中的使用会很有用。

最佳答案

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

/*!
 * @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

这里引用自 dispatch_once 文档:

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 变量必须存储在全局/静态范围内,并且必须初始化为零,这导致了这段代码:

import Foundation

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

如果您省略 = 0(token 初始化),它将不起作用,因为编译器会产生错误 Address of variable 'token' taken before it is initialized 尽管静态变量和全局变量默认为零。在 Xcode 7B2 中测试。


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

您不能在方法内部声明静态属性,否则编译器会产生静态属性只能在类型上声明错误。这不起作用:

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

必须在类型上声明。这是在 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)

那么,如果我们不喜欢全局变量,我们可以做什么?

类型上的静态变量

class MyClass {
  private static var token: dispatch_once_t = 0

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

封装在结构中的方法中的静态

不喜欢你类的静态属性?想在您的方法中使用它吗?像这样将其包装在结构中:

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

实际上,我不知道任何 Apple 推荐、最佳实践,...如何为 dispatch_once 做这件事。只需使用您最喜欢的任何东西,让您感觉良好并满足全局/静态范围的标准。

关于swift - Swift 中 dispatch_once 的例子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31235740/

相关文章:

ios - AVAudioPlayer 不播放声音

Objective-C setFrame Swift 等效项

ios - Swift3 框架模块为空

ios - 为什么不能将 UITableViewCell 实例用作计算属性?

iphone - iOS 通知中的本地化?

xcode - 将窗口显示为模式的问题

ios - 在 Swift 数组中查找第一个元素匹配条件(例如 EKSource)

swift - 如何将类型应用于 NSFetchRequest 实例?

swift - 从标签创建计时器时,使用 Xcode 在 Swift 5 中出错

cocoa - 从代码发送 MouseEvent 到 NSView (WebView)