本帖最后由 liii 于 2015-6-29 14:26 编辑
单例,即单一实例,也就是一个类只允许有一个实例(即,一个对象)
那单例到底用在哪儿呢?,说实话这个我也没理解,感受不到它的用途,相信在以后接触到项目之后,才能真正体会,但是这不影响我们先学会简单的去实现它。
1,创建一个对象有几种方法呢?
1, Person *p = [Person new]; // 第一种方式
2, Person *pp = [[Person alloc] init]; // 第二种方式
3, Person *ppp = [p copy] ; // 第三种方式 (记得要要让Person类先,遵守NSCoping协议)
2,这样创建的对象是几个对象呢?
// 打印输出,看地址是否为同一个,不同则为不同对象,相同则为同一对象
* NSLog(@"\n p = %p \n pp = %p \n ppp = %p", p, pp, ppp);
3, 答案
* new 和 alloc 创建的是不同的新对象,地址不同
* copy 创建的对象ppp 与 pp 对象 是同一个对象,地址相同
4,单例的思想
* 把创建对象的方法重写,让别人在通过这些方法创建对象的时候,都获取已经存在的对象
* 问题来了,已经存在的对象由谁来提供呢,答案:类本身(通过类方法,自己创建自己的对象)
* 给外界只提供一个获取它的方法,像是set方法一样,你要使用我的成员变量,只能使用我的方法
* 这是有个前提的,成员变量需要私有化,不允许别人继承,也不允许直接访问,我对外提供的接口只有一个set方法和get方法
5,问题又来了,怎么实现由类本身提供对象,又怎么通过方法给外界一个获取它的接口呢
// 代码举例:比如有一个Car类,在实现文件中注意
#import <Foundation/Foundation.h>
// 第一步
static Car *shareInstance = nil;
/** 上边这一行,是干什么呢?
* 声明一个Car类型的指针,用来接收对象,为什么要放在这个位置呢?
* 让它变成私有的,只局限于在这个文件中使用,不让它在main函数内使用,如果写在@interface中,只要引入头文件就可以用了
* 那为什加 static 呢? 答:为了让指针里的地址值,不会被清空(就像在代码块内用static修饰 变量n,代码块结束而n的值还会保留一样)
*/
@implementation Car
// 第二步
+ (instancetype)shareInstance{ // 自己提供给外界一个获取对象的方法(接口)
if(shareInstace == nil){ // 如果是第一次创建对象,就创建一个对象
shareInstance = [[self alloc] init]; // 自己创建一个对象赋值给,自己定义的指针,完成对象在,类本身内的创建
return shareInstance; // 将创建好的对象返回
}
return = shareInstance; // 如果已经存在对象(指向对象的指针不为空),则直接返回已经创建好的对象
}
/** 第三步:覆盖掉alloc 方法,copy方法
* 了解一个过程
* 通过 new 或 alloc 方法创建对象的时候,其实是调用了一个类方法
* 即 + (instancetype)allocWithZone:(NSZone *)zone;
* 所以重写它,在方法内部,让他直接放回类已经创建好的对象
* 通过 copy 创建对象的时候,实际是调用了一个 对象方法
* 即 - (instancetype)copyWithZone:(NSZone *)zone;
* 所以也重写它,每当copy的时候,也让他返回已经创建好的对象
*/
+ (instancetype)allocWithZone:(NSZone *)zone{
@synchronized(self){ // 线程保护,固定格式,记住写法即可
if(shareInstace == nil)}{ // 判断是否已经存在新对象
shareInstance = [super allocWithZone:zone]; // 如果不存在,则创建一个新对象
return shareInstance; // 返回刚创建好的对象给调用者
}
return shareInstance; // 如果存在则直接返回已经创建好的对象
}
}
- (instancetype)copyWithZone:(NSZone *)zone{
return self; // 当copy对象的时候,直接返回已经存在的对象
}
@end
/** 第五步
* main函数内创建对象验证,他们是否指向同一个对象(即,内存地址一样)
* 1,通过 类提供给外界的方法 + (instancetype)shareInstance; 创建一个对象
* 2,通过new方法创建一个对象
* 3,通过alloc方法创建一个对象
* 4,通过copy方法创建一个对象
*/
#import <foundation/Foundation.h>
#import "Car.h"
int main()
{
Car *c = [Car shareInstance];
Car *cc = [Car new];
Car *ccc = [[Car alloc] init];
Car *cccc = [ccc copy];
NSLog(@"\n %p \n %p \n %p \n %p", c, cc, ccc, cccc); // 查看地址是否相同,相同即实现了单一实例
retun 0;
}
/** 总结:实现单例的步骤
1,在@implementation文件内创建一个 静态的私有的空的所属类的类型的指针
代码:static Car *shareInstance = nil;
2,提供一个能够自己创建对象的类方法
代码: + (instancetype)shareInstance;
3,重写alloc方法
4,重写copy方法
5,在main函数内创建对象验证
*/
|