【黑马程序员】oc中的单例设计模式

---------- IOS培训java培训、期待与您交流! ----------


什么是单例模式

    简单的说就是使得类的一个对象成为系统的唯一实例。用类来创建的每一个对象都是同一个实例。如果我们用%p来输出打印,我们会发现其内存地址是一样的。
或者说单例模式的意图是是的类的对象成为系统中唯一的实例,提供一个访问点,供客户类共享资源。

什么情况下使用单例?
     1、类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。
     2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。


单例设计模式的要点:

(1) 某个类只能有一个实例。  
(2)他必须自行创建这个对象  
(3)必须自行向整个系统提供这个实例;
 (4)为了保证实例的唯一性,我们必须将
 -(id)copyWithZone:(NSZone *)zone  、+(id)allocWithZone:(NSZone *)zone、 -(id)retain、  -(NSUInteger)retainCount 
-(oneway void)release   -(id)autorelease 的实现方法进行覆盖。
  (5)这个方法必须是一个静态类






一个经典的oc单例模式如下所示:

    

//        static id sharedMyManager;   //注意这里必须在类的.m文件中定义一个全局变量

//        //sharedXXX  defaultXXX currentXXX   //默认的定义单例模式的命名方式

//        

//        +(id)sharedMyManageer{

//            if (sharedMyManager==nil) {  //此处判断是确保实例的唯一性

//                

//                sharedMyManager=[[self alloc]init];

//                

//            }

//            return sharedMyManager; //第一次后每次通过这个类方法创建的对象都是唯一的实例

//        }

//    




说到这里可能大家都了解的差不多了。下面我写了一个小例子来作为最经典简单的单例模式。

在arc模式下:

定义了一个dog类。

//
//  Dog.h
//  笔记
//
//  Created by 肖俊全 on 15/3/2.
//  Copyright (c) 2015年 肖俊全. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Dog : NSObject

@property (nonatomic ,assign) NSString * name;
+(id)sharedMyDog;


@end

//
//  Dog.m
//  笔记
//
//  Created by 肖俊全 on 15/3/2.
//  Copyright (c) 2015年 肖俊全. All rights reserved.
//

#import "Dog.h"

static Dog *dog;   //必须创建一个全局对象

@implementation Dog
+(id)sharedMyDog{
    
    @synchronized(self){ //这段代码让线程进入atomic状态,如果多个线程进入这段代码,这段代码只能一个线程执行
        
        if (dog == nil) {
    //第一次进入,存于全局变量中
        dog=[[self alloc]init];
    }
    }
    return dog;
    
}
- (instancetype)init
{
    self = [super init];
    if (self) {
       self.name=@"wangwang";
    }
    return self;
}

-(NSString *)description{
    
    NSString * name = [NSString stringWithFormat:@"%@",self.name];
    return name;
}

@end

在主函数中,我们对每个对象进行了地址的打印。,,并且打印出每个对象的dog name属性。

//
//  main.m
//  笔记
//
//  Created by 肖俊全 on 15/3/2.
//  Copyright (c) 2015年 肖俊全. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Dog.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        
        
        Dog * d1 =[Dog sharedMyDog];
        Dog * d2= [Dog sharedMyDog];
        
        NSLog(@"d1==%p,d2==%p",d1,d2);
        NSLog(@"d1的名字是%@,d2的名字是%@",d1,d2);
        
        Dog *d3=[Dog sharedMyDog];
        d2.name=@"miaomiao";
        
        NSLog(@"d1==%p,d2==%p,d3=%p",d1,d2,d3);
        NSLog(@"d1的名字是%@,d2的名字是%@,d3的名字是%@",d1,d2,d3);
        
        
        
        
    }
    return 0;
}

运行结果如下:

2015-03-03 15:48:35.949 单例笔记[1514:110062] d1==0x100406940,d2==0x100406940

2015-03-03 15:48:35.950 单例笔记[1514:110062] d1的名字是wangwang,d2的名字是wangwang

2015-03-03 15:48:35.950 单例笔记[1514:110062] d1==0x100406940,d2==0x100406940,d3=0x100406940

2015-03-03 15:48:35.951 单例笔记[1514:110062] d1的名字是miaomiao,d2的名字是miaomiao,d3的名字是miaomiao

Program ended with exit code: 0



在我们改改了d2对象的name属性的同时,d1,d3的name属性也随之改变。因为其内存地址是一样的。在此实现了单例模式。

注意我们在真正需要写或用单例时,千万不要像平时这样创建----Dog *dog=[[Dog alloc]init];

注意:所谓单例,即我们自己创建一个单例,该类只能生成唯一的对象,即用  if (sharesingleton == nil)    方法来保证唯一性,为了防止该对象被复制(copy)或者retain 和 release 等操作,我们必须在所创建的单例的实现文件( .m 文件)中将父类的这些方法给覆盖,该目的是为了保证单例模式的一个严谨性。 




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值