博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Objective-C中单例模式的实现【转】
阅读量:5745 次
发布时间:2019-06-18

本文共 7819 字,大约阅读时间需要 26 分钟。

单例模式在Cocoa和Cocoa Touch中非常常见。比如这两个,[UIApplication sharedApplication][NSApplication sharedApplication],大家应该都见过。但是我们应该如何在代码中实现一个单例模式呢?

如果你对苹果的文档很熟悉的话,你一定知道,在中有一段。大致如下:

1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            20            21            22            23            24            25            26            27            28            29            30            31            32            33            34            35            36            37            38            39            40            41            42            43            44            45            46            47            48            49            50            51            52            53
/* Singleton.h */            #import <Foundation/Foundation.h>                        @interface Singleton : NSObject            + (Singleton *)instance;            @end                        /* Singleton.m */            #import "Singleton.h"            static Singleton *instance = nil;                        @implementation Singleton                        + (Singleton *)instance {
if (!instance) {
instance = [[super allocWithZone:NULL] init]; } return instance; } + (id)allocWithZone:(NSZone *)zone {
return [self instance]; } - (id)copyWithZone:(NSZone *)zone {
return self; } - (id)init {
if (instance) {
return instance; } self = [super init]; return self; } - (id)retain {
return self; } - (oneway void)release {
// Do nothing } - (id)autorelease {
return self; } - (NSUInteger)retainCount {
return NSUIntegerMax; } @end

这是一种很标准的Singleton实现,中规中矩。不过这种实现并不是线程安全的。所以各路大神都各显神威,给出了多种单例模式的实现。

Matt Gallagher在中放出了一个Macro,用来实现单例模式。虽然是一个宏定义的代码,但是具体实现还是很清楚的。代码如下:

1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            20            21            22            23            24            25            26            27            28            29            30            31            32            33            34            35            36            37            38            39            40            41            42            43            44            45            46            47            48            49            50            51            52            53            54            55            56            57            58            59            60            61            62            63            64            65            66            67            68
//            //  SynthesizeSingleton.h            //  CocoaWithLove            //            //  Created by Matt Gallagher on 20/10/08.            //  Copyright 2009 Matt Gallagher. All rights reserved.            //            //  Permission is given to use this source code file without charge in any            //  project, commercial or otherwise, entirely at your risk, with the condition            //  that any redistribution (in part or whole) of source code must retain            //  this copyright and permission notice. Attribution in compiled projects is            //  appreciated but not required.            //                        #define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \             \            static classname *shared##classname = nil; \             \            + (classname *)shared##classname \            { \                @synchronized(self) \                { \                    if (shared##classname == nil) \                    { \                        shared##classname = [[self alloc] init]; \                    } \                } \                 \                return shared##classname; \            } \             \            + (id)allocWithZone:(NSZone *)zone \            { \                @synchronized(self) \                { \                    if (shared##classname == nil) \                    { \                        shared##classname = [super allocWithZone:zone]; \                        return shared##classname; \                    } \                } \                 \                return nil; \            } \             \            - (id)copyWithZone:(NSZone *)zone \            { \                return self; \            } \             \            - (id)retain \            { \                return self; \            } \             \            - (NSUInteger)retainCount \            { \                return NSUIntegerMax; \            } \             \            - (void)release \            { \            } \             \            - (id)autorelease \            { \                return self; \            }

然而,eschaton则觉得这些实现都太繁琐了,他给出的实现如下:

1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            20            21            22            23            24            25            26            27            28            29            30            31            32            33
@interface SomeManager : NSObject            + (id)sharedManager;            @end                        /* 非线程安全的实现 */            @implementation SomeManager                        + (id)sharedManager {
static id sharedManager = nil; if (sharedManager == nil) {
sharedManager = [[self alloc] init]; } return sharedManager; } @end /* 线程安全的实现 */ @implementation SomeManager static id sharedManager = nil; + (void)initialize {
if (self == [SomeManager class]) {
sharedManager = [[self alloc] init]; } } + (id)sharedManager {
return sharedManager; } @end

关于为什么上述代码就能实现单例模式,以及关于线程安全问题的考量,请参考他的。

最后介绍一个比较。为什么说现代呢?因为这种实现利用了GCD(Grand Central Dispatch)和ARC(Automatic Reference Counting)。核心代码如下:

1            2            3            4            5            6            7            8            9
+ (id)sharedInstance            {
static dispatch_once_t pred = 0; __strong static id _sharedObject = nil; dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method }); return _sharedObject; }

作者还写了一个宏()来方便使用,大家可以阅读作者的博文了解详情。

大多数情况下,Apple官方文档里的单例模式的示例代码实现已经够用了。虽然它最繁琐,但是也是本文介绍的几种单例模式中最容易理解的一个。至于其他的实现就留给读者们根据需要选择和应用了。

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 330987132 | Go:217696290 | Python:336880185 | 做人要厚道,转载请注明出处!http://www.cnblogs.com/sunshine-anycall/archive/2012/05/31/2528650.html
你可能感兴趣的文章
shell高级视频答学生while循环问题
查看>>
无法SSH到Ubuntu
查看>>
使用@media实现IE hack的方法
查看>>
《11招玩转网络安全》之第一招:Docker For Docker
查看>>
hive_0.11中文用户手册
查看>>
hiveserver2修改线程数
查看>>
XML教程
查看>>
oracle体系结构
查看>>
Microsoft Exchange Server 2010与Office 365混合部署升级到Exchange Server 2016混合部署汇总...
查看>>
Proxy服务器配置_Squid
查看>>
开启“无线网络”,提示:请启动windows零配置wzc服务
查看>>
【SDN】Openflow协议中对LLDP算法的理解--如何判断非OF区域的存在
查看>>
纯DIV+CSS简单实现Tab选项卡左右切换效果
查看>>
栈(一)
查看>>
ios 自定义delegate(一)
查看>>
创建美国地区的appleId
查看>>
例题10-2 UVa12169 Disgruntled Judge(拓展欧几里德)
查看>>
[c语言]c语言中的内存分配[转]
查看>>
JS 原生ajax写法
查看>>
day 10 字符编码和文件处理 细节整理
查看>>