学习如何做网站,做电视网站需要多大的服务器,图片发到哪些网站 seo,广州微信营销公司一、概述#xff1a; 有一些对象我们只需要一个#xff0c;比方说#xff1a;线程池#xff08;threadpool#xff09;、缓存#xff08;cache#xff09;、对话框、处理偏好设置和注册表对象、日志对象、充当打印机、显卡等设备的驱动程序的对象。事实上这些对象只需要…一、概述 有一些对象我们只需要一个比方说线程池threadpool、缓存cache、对话框、处理偏好设置和注册表对象、日志对象、充当打印机、显卡等设备的驱动程序的对象。事实上这些对象只需要一个实例如果制造出多个实例就会导致很多问题发生。利用静态类变量、静态方法和适当的访问修饰符的确也可以做到只存在一个实例。 苏格拉底诱导式回答参考《Head First 设计模式》 如何创建一个对象new MyObject万一另外一个对象想创Myobject会怎样可以再次new MyObject吗?是的当然可以。所以一旦有一个类我们是否都能多次的实例化它如果是公开的类 就可以如果不是的话会怎样 如果不是公开的类只有同一个包内的类可以实例化它但是仍可以实例化它很多次 可以这么做吗 public Myclass
{private Myclass{}
} 我没想过但是这是合法的定义有一定的道理。 怎么说呢 我认为含有私有的构造器类不能呗实例化。 又可以使用私有的构造器对象吗 恩我想Myclass内的代码是唯一能调用此构造器的代码但是这又不太合乎常理。 WHY 因为只有Myclass的实例才能调用Myclass的构造器但是因为没有其他类能够实例化Myclass所以我们得不到这样的实例。 嘿我有个想法。 你认为如何 public Myclass
{public static MyClass getInstance{}
} MyClass有一个静态方法我们可以这样调用这个方法 MyClas.getInstance 为何调用的时候用MyCLass类名而不是对象名。 因为getInstance是类方法是一个静态方法你需要使用类名。 有意思假如把这些合在一起“是否”就可以初始化一个MyClass public MyClass
{private MyClass{}public static Myclass getInstance{return new MyClass}
} 当然可以 好了你能想出第二种实例化对象的方式吗 MyClass.getInstance(); 你能够完成代码是MyClass只有一个实例被产生吗 恩大概可以吧。。。。 单例模式优点 正如前面说的单例模式在内存中只有一个实例减少了内存开支。特别是一个对象需要频繁的创建、销毁时而创建与销毁的性能有无法优化单例模式的优势就非常明显。单例模式只生成一个实例减少了系统性能开销当一个对象的产生需要比较多的资源时如读取配置、产生其他依赖对象时则可以通过在应用启动时直接产生一个单例对象然后永久驻留内存的方式来解决。单例模式可以避免对资源的多重占用。单例模式可以在系统设置全局的访问点优化和共享资源访问。单例模式缺点 单例模式一般没有接口扩展很困难除了修改代码基本上没有第二种途径实现。单例模式对测试是不利的。在并行开发环境中如果单例模式没有完成是不能进行测试的。单例模式与单一职责原则有冲突。二、在IOS中的应用 单例模式在iOS开发中的使用还是蛮多的许多Foundation、Cocoa和UIKit中的类都实现了单例模式比如应用程序本身UIApplication、文件操作类NSFileManager、消息中心NSNotificitonCenter等系统都已经给我们实现单例我们只需要使用就好了。在iOS中使用单例模式要使用类方法通过类方法返回该类的唯一对象。 在ios中的应用主要有以下三种方式 1、 static Singleton *instance nil; (Singleton *)sharedInstance
{if (instance nil) {instance [[super allocWithZone:NULL] init];}return instance;
} (id)allocWithZone:(NSZone *)zone
{return [[self sharedInstance] retain];
}- (id)copyWithZone:(NSZone *)zone
{return self;
}- (id)retain
{return self;
}- (NSUInteger)retainCount
{return NSUIntegerMax; //denotes an object that cannot be released
}- (void)release
{//do nothing
}- (id)autorelease
{return self;
} 可以看到这种方式使用静态成员维持了一个永久存在的对象而且覆盖了alloc方法alloc方法会调用allocWithZone:方法并且也覆盖了所有与引用技术有关的方法这都使这个对象不会被销毁。这样看上去基本实现了我们需要的但是写起来麻烦不说还有很大的一个问题那就是多线程问题如果是在多线程中那么该种方法就不能保证只产生一个对象了。所以这种方式只是介绍一下并不推荐使用。 2、引入头文件 程序员都是偷懒的现在流行使用一个宏定义来搞定这许多的事而且考虑的更加周全。 单例包含以下接口 (MyClass*) sharedInstance; (void) purgeSharedInstance; 调用sharedInstance会创建并返回单例 调用purgeSharedInstance会销毁单例 手动调用alloc也可以保证是单例你可以这样调用 [[MyClass alloc] initWithParam:firstParam secondParam:secondParam]; 只是要保证在sharedInstance之前调用因为只有一次创建机会。 下面是使用宏的写法“ MyClass.h: #import SynthesizeSingleton.h interface MyClass: SomeSuperclass { ... } SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass); end MyClass.m: #import MyClass.h implementation MyClass SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass); ... end 开源库下载地址 3、 iOS在4.0以后推出了block和GCD这两个特性给iOS开发带来的很大的便利也使开发变得更加趣味话。那么如何通过GCDblock来实现单例模式呢这主要归功于dispatch_once(dispatch_once_t *predicate, ^(void)block)这个GCD的函数他有两个参数第一参数是一个指向dispatch_once_t类型结构体的指针用来测试block是否执行完成该指针所指向的结构体必须是全局的或者静态的第二个参数是一个返回值与参数均为空的block在block体中进行对象的初始化即可。dispatch_once在程序的生命周期中保证只会被调用一次所以在多线程中也不会有问题。 该种方法使用方法 (Singleton *)sharedInstance
{static Singleton *instance nil;static dispatch_once_t onceToken;dispatch_once(onceToken, ^{instance [[Singleton alloc]init];});return instance;
} dispatch_once的作用就是执行且在整个程序的声明周期中仅执行一次某一个block对象。简直就是为单例而生的嘛。而且有些我们需要在程序开头初始化的动作如果为了保证其仅执行一次也可以放到这个dispatch_once来执行。 然后我们看到它需要一个断言来确定这个代码块是否执行这个断言的指针要保存起来相对于第一种方法而言还需要多保存一个指针。 方法简介中就说的很清楚了对于在应用中创建一个初始化一个全局的数据对象单例模式这个函数很有用。 如果同时在多线程中调用它这个函数将等待同步等待直至该block调用结束。 这个断言的指针必须要全局化的保存或者放在静态区内。使用存放在自动分配区域或者动态区域的断言dispatch_once执行的结果是不可预知的。 总结1.这个方法可以在创建单例或者某些初始化动作时使用以保证其唯一性。2.该方法是线程安全的所以请放心大胆的在子线程中使用。前提是你的dispatch_once_t onceToken 对象必须是全局或者静态对象。这一点很重要如果不能保证这一点也就不能保证该方法只会被执行一次。 参考博客 水滴石穿 Keeping faith. --- wtluckys Blog 转载于:https://www.cnblogs.com/ymonke/p/3513668.html