单例设计模式

 写一个Person类,要保证无论什么情况下创建Person对象返回的都是同一个对象(单例设计模式


单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。


通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。

一个最好的办法就是,让类自身负责保存它的唯一实例。

这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。


因为要保证类型对象的单一性,所以就要考虑Objective C在实例化对象时候的各种方式。

因为在Objective C中创建的各个类型都继承自NSObject类型,所以我们需要考虑

NSObject类型里实例化的方法,下面让我们展开来说。


在Objective C的实例化对象的方式主要有两种,分别如下:

obj = [NSObject new];

obj = [[NSObject alloc]init];

第一种方式,用new方法初始化其实是第二种方式的总和,当调用new方法时,其实是先调用了alloc方法进行isa(is a pointer)操作,创建指针,指向内存中的数据结构,紧接着调用了init方法对数据进行初始化。

第二种方式看起来就很明确了,先调用alloc创建指针指向内存中的数据结构,再调用init方法初始化数据。这里需要注意的是,init方法只是起到了初始化数据的作用,其实也可以自定义初始化方法,即完全可以自定义一个普通返回NSObject类型的方法来代替init方法,即init方法是可以随意被代替的。只不过NSObject类型中new方法默认会调用init方法而已,init方法可以看作是NSObject类型的默认构造函数。


所以综上所述,其实只有alloc方法是每次必须调用的方法,那么我们只要控制住alloc方法,对此方法进行覆盖就可以保证类型对象的单一性了。



#import <Foundation/Foundation.h>

@interface Person : NSObject

+ (Person *)getPerson;

+ (id)allocWithZone:(NSZone *)zone;

- (id)copyWithZone:(NSZone *)zone;

- (id)retain;

- (NSUInteger)retainCount;

- (void)release;

- (id)autorelease;

@end

#import "Person.h"

@implementation Person

+ (Person *)getPerson

{

    static Person *person = nil; // 静态的该类的实例

    if(person == nil)   // 只有为空的时候构建实例

    {

        person = [[super allocWithZone:NULL] init];

    }

    return person;

}

+ (id)allocWithZone:(NSZone *)zone

{

    return [[self getPerson] retain];   //返回单例

}

- (id)copyWithZone:(NSZone *)zone

{

    return self;

}

- (id)retain

{

    return self;

}

- (NSUInteger)retainCount

{

    return NSUIntegerMax;

}

- (void)release

{}

- (id)autorelease

{

    return self;

}

@end

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

    @autoreleasepool {

    

        Person *p1 = [Person alloc];

        Person *p2 = [Person getPerson];

        Person *p3 = [Person alloc];

        NSLog(@"\n\n%@\n%@\n%@\n", p1, p2, p3);

    }

    return 0;

}



执行后打印出来的三个实例的地址是一样的:

p1, p2, p3

说明它们是同一个实例,无论是 alloc 还是 getPerson.

1. 每一次 alloc 都得经过 allocWithZone: 方法,然后进到 getPerson方法,这就统一了入口
2. release/autorelease/retainCount 方法保证了实例不被释放
3. copyWithZone: 和 retain 用以确保克隆还是保留的仍然是原来那个唯一的实例


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值