黑马程序员技术交流社区

标题: oc中的单例模式 [打印本页]

作者: Micro    时间: 2015-3-4 22:02
标题: 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 micro 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 micro 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 micro 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 文件)中将父类的这些方法给覆盖,该目的是为了保证单例模式的一个严谨性。







作者: Micro    时间: 2015-3-4 22:05
由于显示的原因。。。欢迎到我的博客去看:::http://blog.csdn.net/oflyme12
作者: itheima2xy    时间: 2015-3-5 09:46
写得很好,给你点个赞!!{:2_30:}
作者: keeganlee    时间: 2015-3-5 09:49
顶起来

作者: manitowang    时间: 2015-3-10 22:07
赞一个!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2