天天看点

iOS 使用 dispatch_once 创建线程安全的单例 使用 dispatch_once 创建单例 Creating singletons using dispatch_once

无论喜欢与否,有时你确实需要使用单例。事实上,每一个 iOS 和 Mac OS 应用都至少用到了一个单例:UIApplication 或NSApplication。

Love them or loathe them, sometimes you need to have a singleton. In fact every iOS and Mac OS application has at least one, UIApplication or NSApplication.

在软件工程学中,单例模式是一种设计模式用于实现数学上的单元素集合的概念,它是通过将一个类的实例限定到唯一的一个对象来实现的。 In software engineering, the singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object.

或者按我的话说:

Or as I would put it:

单例是一个类,这个类只有一个实例被实例化。 A singleton is a class, where only one instance of it can instantiated.

尽管这是单例的实际定义,但在基础库世界中并不总是这种状况。以NSFileManger 和NSNotificationCenter 为例,通常通过它们的类方法defaultManager

和defaultCenter 被分别访问。尽管没有限制一个单例,但它们的类方法确总是返回一个共享的该类的实例,以例开发者随后通过代码能够访问。这就是我们本次将会看到的这种方法。

Although this is the actual definition of a singleton, this isn’t always the case in the world of Foundation.NSFileManger and NSNotificationCenter for example, are usually accessed through

their class methodsdefaultManager and defaultCenter respectively. Although not strictly a singleton, these class methods return a shared instance of that class that developers can then

access throughout their code. It is this approach that we will be looking at in this post.

这个函数就是

dispatch_once :

This function is dispatch_once:

This function takes a predicate (which is a long, that in reality acts as a BOOL) that the dispatch_once function uses

to check if the block has already been dispatched. It also takes the block that you wish to only be dispatched once for the lifetime of the application, for us this is the instantiation of our shared instance.

Not only does dispatch_once mean that your code will only ever get run once, it is also thread safe, which means you don’t have to bother with using

anything like @synchronized to stop things getting out of sync when using multiple threads and/or queues.

If called simultaneously from multiple threads, this function waits synchronously until the block has completed.

So how would you use this in practise?

Well lets say you have a Account Manager class, and you want to access a shared instance of this class throughout your application. You can simply

implement a class method like the one below:

This means whenever you want access this shared instance all you need to do is:

And that’s all there is to it, you now have a shared instance that you can access throughout your application, which will only be created once.

This approach has many advantages:

It is thread safe

It will keep the static analyser happy

It is compatible with Automatic Reference Counting (ARC)

It only requires a small amount of code

The only disadvantage with this approach is that it will still allow a non shared instance to be created:

Sometimes you will actually want this behaviour, but it is something you need to be aware of when you really only want one instance of a class to ever be instantiated.

your own site.

继续阅读