objective-c設計模式之---單例

單例模式能夠說是每一個應用都有用到的一個模式,在iOS的世界裏更是常見。例如咱們的UIApplication sharedApplicaiton應用的就是單利模式, defaultManager和defaultCenter等也是常見的單利。這也是爲何人們常常把CoreData的實例變量放在UIApplication裏面。 html

對單例有了更清楚的瞭解之後,咱們能夠讓咱們的代碼更加清晰。好比,咱們能夠把放在AppDelegate裏的關於CoreData的代碼移植到其餘的單例類裏面。 安全

在相關網絡博客上面看到了下面三種實現單利的方法。 網絡

1. 使用GCD實現單線程實現(給一篇參考文章http://bj007.blog.51cto.com/1701577/649413 app

void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);其中第一個參數predicate,該參數是檢查後面第二個參數所表明的代碼塊是否被調用的謂詞,第二個參數則是在整個應用程序中只會被調用一次的代碼塊。dispach_once函數中的代碼塊只會被執行一次,並且仍是線程安全。 函數

@implementation MyClass

#pragma mark Singleton Methods

+ (id)sharedClass {
    static MyClass *sharedMyClass = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyClass = [[self alloc] init];
    });
    return sharedMyClass;
}

@end
2. 加上同步

+ (id)sharedClass {

    static MyClass *sharedMyClass = nil;
    @synchronized(self) {
        if (sharedMyClass == nil)
            sharedMyClass = [[self alloc] init];
    }
    return sharedMyClass;
}

3. 沒有ARC的同步實現(官網給出的也是這種方式 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32 ui

+ (id)sharedClass {
  @synchronized(self) {
      if(sharedMyClass == nil)
          sharedMyClass = [[super allocWithZone:NULL] init];
  }
  return sharedMyClass;
}
+ (id)allocWithZone:(NSZone *)zone {
  return [[self sharedMyClass] retain];
}
- (id)copyWithZone:(NSZone *)zone {
  return self;
}
- (id)retain {
  return self;
}
- (unsigned)retainCount {
  return UINT_MAX;
}
- (oneway void)release {
  // never release
}
- (id)autorelease {
  return self;
}
4. 其實還有其餘的方式來實現。好比你將同步的代碼快寫到一個SynthesizeSingleton.h的頭文件裏。

#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; \
} \
\
在相關的類

@interface Preference : NSObject

+ (Preference *)sharedPreference;

在類的實現里加上 spa

#import "SynthesizeSingleton.h"

@implementation Preference

SYNTHESIZE_SINGLETON_FOR_CLASS(Preference);

這種方式無疑是最簡單也最易複用的方式。使用的時候直接調用shareXxx就能夠了。 線程

相關文章
相關標籤/搜索