iOS 单例模式

iOS singleton

Singleton(单例模式)是一种很常见的模式,仔细看了下。其实OC里面和java 还是有些不同的。 不同体现在,java 可以将构造方法(相当于oc 里面 alloc init)设置成为 private(私有),这样当别的地方去实例化一个对象的时候就发现无法使用构造方法了,从而使用 getInstence(或者其它的)去实例化一个新的对象。这样一来在getInstence里面做一些操作即可以保证单例类。

而oc里面是无法私有alloc 方法,所以当我们写了相对应的类方法 getInstence,别的地方还是可以利用 alloc init 出新的对象出来的。所以在oc里面还需要对 alloc 方法进行处理。当然oc里面还有别的比如 copy。(考虑到 ARC 就不说一些 release 方法了)

下面是我自己写的一个单例类:
h文件,比较简单就是基本的东西 name 是为了测试添加的

#import <Foundation/Foundation.h>
@interface PersonFactory : NSObject
@property(nonatomic,strong)NSMutableString *name;
+(id)defaultPersonFactory;
@end  

m文件,

#import "PersonFactory.h"

@implementation PersonFactory

static PersonFactory *sharedPersonFactory = nil;

//重写allocWithZone方法
+(id)allocWithZone:(NSZone *)zone{
    @synchronized (self) {
        if (sharedPersonFactory == nil) {
            sharedPersonFactory = [super allocWithZone:zone];
        }
        if (sharedPersonFactory.name == nil) {
            sharedPersonFactory.name = [[NSMutableString alloc]init];
        }
        [sharedPersonFactory.name setString:@"alloc!"];
        return sharedPersonFactory;
    }
}

+(id)defaultPersonFactory{

    if (sharedPersonFactory == nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedPersonFactory = [[self alloc]init];
            if (sharedPersonFactory.name == nil) {
                sharedPersonFactory.name = [[NSMutableString alloc]init];
            }
            [sharedPersonFactory.name setString: @"test"];
        });
    }
    return sharedPersonFactory;
}

-(id)copyWithZone:(NSZone *)zone{
    return self;
}

@end  

测试代码:

-(void)testSingleton{
    PersonFactory *personFac1 = [PersonFactory defaultPersonFactory];
    NSLog(@"perFac1 name is %@ %p", personFac1.name, personFac1);

    PersonFactory *personFac2 = [[PersonFactory alloc]init];
    NSLog(@"perFac2 name is %@ %p", personFac2.name, personFac2);

    PersonFactory *personFac3 = [personFac1 copy];
    NSLog(@"perFac3 name is %@ %p", personFac3.name, personFac3);
}   

测试输出log:

perFac1 name is test 0x7b8a8ad0
perFac2 name is alloc! 0x7b8a8ad0
perFac3 name is alloc! 0x7b8a8ad0

可能存在的问题

  • 刚刚说的重写重alloc/copy方法,为什么没有重写?
    因为 alloc 方法调用的还是 allocWithZone 方法,copy也一样,如果只重写 alloc,还是可以通过 allocWithZone 来构造出新的对象。
  • synchronized 只是保证只有同一时间只有一个操作对当前 self的操作。
  • dispatch_once 代表里面的代码只会执行一次。
  • 为什么不直接重写 alloc 或者 allocWithZone 方法??
    我自己想的是因为不能私有化 alloc/allocWithZone ,这样用 alloc/allocWithZone 根本就不知道这个类是单例的,解释好牵强…

其它问题:
在NSObject 的h文件里找到

- (id)copy;
- (id)mutableCopy;

+ (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE;

可以看到的是copyWithZone是类方法,为什么在调用 copy 方法的时候会去找对象方法 copyWithZone ?
www.rainkong.net

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值