OC中的单例
单例,简单的语言概括,就是唯一的一个实例,也就是唯一的一个对象,大家都对同一个对象进行操作。
在Foundation框架中,很多的类中都用到了单例这种编程模式,它是处理数据共享的最常用的一种方法。
单例的理解
简单的理解,就是在开发过程中,有时会需要在不同的地方对同一块内存的数据进行操作,而对于OC来讲,这块内存往往代表的是一个对象的数据。
所以想出了这样一种办法:就是可以通过一个类方法直接返回一个本类的对象(必须是类方法,因为如果是对象方法,在调用的时候还要声明一个该类的对象并对其初始化,而这个对象本身没有实际作用,无故的占用了内存空间),而且保证这个对象只被分配一次内存空间(这样才能保证通过这个对象永远能够对那块内存空间进行操作),通过这种方式,在整个工程中,你只要想读取这块内存中的数据,就可以通过调用该类的类方法返回这个唯一的对象。
单例的实例
这个例子模拟的是两个人ZhangSan和LiSi合租了一辆车,通过记录每个人开车的时间,最后统计出这辆车总共跑的小时数。
创建一个工程,例如:Share;
创建两个类,一个是Person类;一个是Car类;
由于两个人共用一辆车,所以Car类中有一个单例,我们先来看Car类的代码实现:
Car.h中的代码:
Car.h中声明了一个纪录总时间的属性和一个类方法。
关键的代码在Car.m中,首先我们声明了一个全局本类的对象(这个对象必须赋空值):
static关键字在这里的作用是:使这个对象只分配一次内存(static还有很多特性)。
在car的类方法中,我们首先判断car对象是否是空值,如果是空值,我们才给它初始化。否则,说明它已经被使用过了,就直接返回,不进入if语句。
下面,我们来看一下Person类中的代码实现:
Person.h的代码:
在main.m中,无论是哪个对象调用这个类方法,返回的都是相同的对象,对同一块内存数据做操作。这就是单例的实际作用。
我们已经学习了很多方法传递数据了,每种方式有它特有的优势,这个需要在不断地实践中,体会它们,在适当的地方使用适当的传递方法。
单例,严格来说应该是工程中需要共享数据时才使用,如果用单例只是去传递数据,那就有点大材小用了。
在Foundation框架中,很多的类中都用到了单例这种编程模式,它是处理数据共享的最常用的一种方法。
单例的理解
简单的理解,就是在开发过程中,有时会需要在不同的地方对同一块内存的数据进行操作,而对于OC来讲,这块内存往往代表的是一个对象的数据。
所以想出了这样一种办法:就是可以通过一个类方法直接返回一个本类的对象(必须是类方法,因为如果是对象方法,在调用的时候还要声明一个该类的对象并对其初始化,而这个对象本身没有实际作用,无故的占用了内存空间),而且保证这个对象只被分配一次内存空间(这样才能保证通过这个对象永远能够对那块内存空间进行操作),通过这种方式,在整个工程中,你只要想读取这块内存中的数据,就可以通过调用该类的类方法返回这个唯一的对象。
单例的实例
这个例子模拟的是两个人ZhangSan和LiSi合租了一辆车,通过记录每个人开车的时间,最后统计出这辆车总共跑的小时数。
创建一个工程,例如:Share;
创建两个类,一个是Person类;一个是Car类;
由于两个人共用一辆车,所以Car类中有一个单例,我们先来看Car类的代码实现:
Car.h中的代码:
#import <Foundation/Foundation.h> @interface Car : NSObject @property (nonatomic,assign)int driveHours; +(instancetype)car; @endCar.m中的代码:
#import "Car.h" static Car * car=nil; @implementation Car +(instancetype)car{ if (car==nil) { car=[[Car alloc] init]; } return car; } @end分解一下Car类中的代码:
Car.h中声明了一个纪录总时间的属性和一个类方法。
关键的代码在Car.m中,首先我们声明了一个全局本类的对象(这个对象必须赋空值):
static关键字在这里的作用是:使这个对象只分配一次内存(static还有很多特性)。
在car的类方法中,我们首先判断car对象是否是空值,如果是空值,我们才给它初始化。否则,说明它已经被使用过了,就直接返回,不进入if语句。
下面,我们来看一下Person类中的代码实现:
Person.h的代码:
#import <Foundation/Foundation.h> #import "Car.h" @interface Person : NSObject @property (nonatomic,copy)NSString * name; @property (nonatomic,strong)Car * car; -(void)displayWithDriveHours:(int)hours; @endPerson.m中的代码:
#import "Person.h" @implementation Person -(instancetype)init{ if (self=[super init]) { self.car=[Car car];//创建对象的car属性实际上就是Car类的那个唯一的实例。 self.name=nil; } return self; } -(void)displayWithDriveHours:(int)hours{ self.car.driveHours+=hours; } @endmain.m文件中代码:
import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { Person * ZhangSan=[[Person alloc] init]; Person * LiSi=[[Person alloc] init]; [LiSi displayWithDriveHours:5]; [ZhangSan displayWithDriveHours:10]; [LiSi displayWithDriveHours:3]; Car * car=[Car car]; NSLog(@"The allHours are %d",car.driveHours); return 0; }输出结果:The allHours are 18
在main.m中,无论是哪个对象调用这个类方法,返回的都是相同的对象,对同一块内存数据做操作。这就是单例的实际作用。
我们已经学习了很多方法传递数据了,每种方式有它特有的优势,这个需要在不断地实践中,体会它们,在适当的地方使用适当的传递方法。
单例,严格来说应该是工程中需要共享数据时才使用,如果用单例只是去传递数据,那就有点大材小用了。