相关疑难解决方法(0)

在Swift中使用dispatch_once单例模型

我正在尝试找出适合在Swift中使用的单例模型.到目前为止,我已经能够得到一个非线程安全模型:

class var sharedInstance: TPScopeManager {
    get {
        struct Static {
            static var instance: TPScopeManager? = nil
        }

        if !Static.instance {
            Static.instance = TPScopeManager()
        }

        return Static.instance!
    }
}
Run Code Online (Sandbox Code Playgroud)

在Static结构中包装单例实例应允许单个实例在没有复杂命名方案的情况下不与单例实例发生冲突,并且它应该使事情变得相当私密.显然,这个模型不是线程安全的,所以我尝试将dispatch_once添加到整个事情中:

class var sharedInstance: TPScopeManager {
    get {
        struct Static {
            static var instance: TPScopeManager? = nil
            static var token: dispatch_once_t = 0
        }

        dispatch_once(Static.token) { Static.instance = TPScopeManager() }

        return Static.instance!
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到一个编译器错误dispatch_once:

无法将表达式的类型'Void'转换为'()'类型

我已经尝试了几种不同的语法变体,但它们似乎都有相同的结果:

dispatch_once(Static.token, { Static.instance = TPScopeManager() })
Run Code Online (Sandbox Code Playgroud)

dispatch_once使用Swift 的正确用法是什么?我最初认为问题出在块中,因为dispatch_once错误消息,但我看的越多,我认为可能是获得() …

singleton dispatch swift

563
推荐指数
10
解决办法
13万
查看次数

可以在单元测试中重置dispatch_once的状态,使它们再次运行

是否可以在单元测试tearDown中重置dispatch_once代码的状态?

我认为如果我们的单元测试可以从一个非常干净的状态运行会很好,但我们正在努力使用dispatch_once和一些使用dispatch进行的单例测试.

objective-c grand-central-dispatch

32
推荐指数
1
解决办法
1万
查看次数

如何在Swift中执行一次代码只执行一次?

到目前为止,我已经看到了这些问题的答案(1,2,3)建议使用GCD是dispatch_once这样的:

var token: dispatch_once_t = 0
func test() {
    dispatch_once(&token) {
        print("This is printed only on the first call to test()")
    }
    print("This is printed for each call to test()")
}
test()
Run Code Online (Sandbox Code Playgroud)

输出:

This is printed only on the first call to test()
This is printed for each call to test()
Run Code Online (Sandbox Code Playgroud)

但是等一下.token是一个变量,所以我可以很容易地做到这一点:

var token: dispatch_once_t = 0
func test() {
    dispatch_once(&token) {
        print("This is printed only on the first call …
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch swift

15
推荐指数
3
解决办法
2万
查看次数

每个对象使用dispatch_once_t而不是每个类

有多个源调用特定方法,但我想确保它被调用一次(每个对象)

我想使用类似的语法

// method called possibly from multiple places (threads)
-(void)finish
{

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self _finishOnce]; // should happen once per object
    });
}
// should only happen once per object
-(void)_finishOnce{...}
Run Code Online (Sandbox Code Playgroud)

问题是令牌是在同一个类的所有实例中共享的 - 所以不是一个好的解决方案 - 每个对象是否有dispatch_once_t - 如果不是,确保它被调用一次的最佳方法是什么?

编辑:

这是我想到的一个提议的解决方案 - 它看起来好吗?

@interface MyClass;

@property (nonatomic,strong) dispatch_queue_t dispatchOnceSerialQueue; // a serial queue for ordering of query to a ivar

@property (nonatomic) BOOL didRunExactlyOnceToken;

@end

@implementation MyClass

-(void)runExactlyOnceMethod
{
  __block BOOL didAlreadyRun = NO;
  dispatch_sync(self.dispatchOnceSerialQueue, ^{
     didAlreadyRun …
Run Code Online (Sandbox Code Playgroud)

singleton objective-c grand-central-dispatch

10
推荐指数
2
解决办法
5592
查看次数

Cocoa dispatch_once每个实例

如何使用displatch_once,因此每个实例生命周期执行一次给定的代码

等价的是在对象中有一个属性,并像这样使用它

- (void)viewWillAppear:(..).. {

   ...

   if (self.isDisplatched == NO) {
      ...
      self.isDisplatched = YES;
   }

}
Run Code Online (Sandbox Code Playgroud)

但我不想使用额外的属性,而是dispatch_once_t或simmilar

cocoa objective-c ios

6
推荐指数
1
解决办法
1694
查看次数

仅在Swift中对象的生命周期中调用一次方法

假设我们覆盖scrollViewDidScroll方法,并且只有第一次滚动,我们想要doSomething()

一个简单的方法是实现这是一个实例级布尔变量并切换/检查它.

func scrollViewDidScroll(scrollView: UIScrollView!) {
  if(!scrolled) {
   scrolled = true; 
   doSomething(); 
  }
}
Run Code Online (Sandbox Code Playgroud)

我想要一个不引入布尔变量的更好的解决方案scrolled.类似dispatch_once但对象的生命周期而不是整个过程.

这个模式有名字吗?

cocoa-touch ios swift

3
推荐指数
1
解决办法
605
查看次数

在初始化闭包时访问“self”

在 Swift 3 中,dispatch_once 函数被移除,迁移指南建议使用初始化闭包:

let myGlobal = { ... global 在对闭包的调用中包含初始化 ... }()

_ = myGlobal // 使用 myGlobal 将仅在第一次使用时调用初始化代码。

我想从初始化闭包中访问“self”实例变量,如下所示:

class SomeClass {
    var other = SomeOtherClass()
    
    let initialize: () = {
        // self.other - this doesn't work, complains about unresolved identifier 'self'
        // how to access self.other here?
    } ()

    func doSomething() {
        // initialize will only be called once
        initialize
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么在闭包中无法访问“自我”,以及如何使其成为?

swift swift3

2
推荐指数
1
解决办法
2269
查看次数