[Objective-C] 단일 모드의 실현

93435 단어
단일 모드는 코코아와 코코아 터치에서 흔히 볼 수 있다.예를 들어 이 두 개[UIApplication sharedApplication][NSApplication sharedApplication]는 모두 본 적이 있을 것이다.그러나 우리는 어떻게 코드에서 하나의 단일 모델을 실현해야 합니까?
만약 애플의 문서에 익숙하다면, 코코아 Foundamentals Guide에 단일 모드를 실현하는 예시 코드가 있다는 것을 틀림없이 알고 있을 것이다.대체로 다음과 같다.
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; } 

저자가 쉽게 사용할 수 있도록 매크로(gist)를 썼는데, 저자의 블로그 A note on Objective-C singletons를 읽어 자세한 내용을 알 수 있다.
대부분의 경우 애플 공식 문서의 예시 모드의 예시 코드는 이미 충분하다.비록 그것이 가장 번거롭지만 본고에서 소개한 몇 가지 단례 모델 중 가장 이해하기 쉬운 것이다.다른 실현은 독자들에게 필요에 따라 선택하고 응용하도록 남겨 두었다.

좋은 웹페이지 즐겨찾기