//标准的单例写法
//以创建歌曲的管理者为例进行创建。
+(instancetype) sharedQYSongManager { static QYSongsManager *songManager =nil;
//采用GDC标准单例实现方法 static dispatch_once_t onceToken; //在程序的生命周期内,该块对象执行一次且仅为一次。
dispatch_once(&onceToken,^{
songManager =[[self alloc] init];
});
return songManager;
}
创建完成后songManager即为单例的对象,即在内存中不管alloc多少个对象都是指的是同一个对象。
有几点需要说明:
1.instancetype是什么?
苹果官方给出的解释是:Use the instancetype keyword as the return type of methods that return an instance of the class they are called on (or a subclass of that class). These methods include alloc, init, and class factory methods.
//iOS开发:CLang添加了一个新的关键字:instancetype;这是一个上下文相关的关键字,并只能作为Objective-C方法的返回类型。使用instancetype可让编译器准确推断返回的具体类型,把一些运行时的错误在编译时暴露出来
下面我们来看一个苹果官方给出的例子
@interface MyObject : NSObject + (instancetype)factoryMethodA; + (id)factoryMethodB; @end @implementation MyObject + (instancetype)factoryMethodA { return [[[self class] alloc] init]; } + (id)factoryMethodB { return [[[self class] alloc] init]; } @end void doSomething() { NSUInteger x, y; x = [[MyObject factoryMethodA] count]; // Return type of +factoryMethodA is taken to be "MyObject *" y = [[MyObject factoryMethodB] count]; // Return type of +factoryMethodB is "id" }
因为+ factoryMethodA的instancetype返回类型,该消息表达式的类型是为MyObject*。由于MyObject来没有一个计数方法,编译器给出了一个关于x行警告:
main.m: ’MyObject’ may not respond to ‘count’
2.dispatch_once_t 谓词用于与dispatch_once功能使用。这种类型的变量必须有全局或静态范围。使用这种类型的自动或动态分配的结果是不确定的。
3.dispatch_once 结构如下,定义在 dispatch/once.h头文件中。
void dispatch_once(
dispatch_once_t *predicate,
dispatch_block_t block);
有两个参数 ,第一参数:是一个指针,用于测试该block块是否已经完成。
第二个参数:是个block块,并且只执行一次。
对于这个参数有以下几点说明 :
1 此功能可用于全局数据(单例对象)在应用程序的初始化非常有用。使用或测试由该块初始化的变量之前,一定要调用这个函数。
2 如果从多个线程中使用,这个函数会等待直到同步块已经完成。
3谓词必须指向存储在全局或静态范围的变量。使用谓词自动或动态存储(含Objective-C的实例变量)的结果是不确定的。