Singleton... 자주 언급되는데 막상 서적이나 Web 상에 많은 정보가 없네요... 소스야 짜면 짤수록 실력이야 느는게 당연한 것이고, 좀 더 깊게 공부하기 위해서 '디자인 패턴'과 '아키텍쳐' (개발구조)등에 대해서 쉬는날은 짬짬히 공부를 진행해야 할 것 같습니다.
금일은 Singleton, Singleton 이 뭔지에 대해서 공부를 해볼까 합니다. (국내에는 정보가 없고 외국사이트 http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html를 참조했습니다)
"전역변수"란 경험이 있는 프로그래머들에게는 두려움을 불러일으키는 용어라고 하는군요. 하지만 실제 전역변수는 어플리케이션에서 필요합니다. 전역변수를 사용하는 경우는,
1. 자신이 소유하고 관리해야 하는 객체가 없는 경우
2. 전 프로그램을 통해 딱 하나만 필요한 경우
3. 그렇다고 상수는 아닌 것 (String 값이나 Number 값)
전역변수를 쓰지 않는 경우는,
1. 자신이 소유하고 관리해야 하는 객체가 있는 경우
2. #Define 한 경우
전역 변수랑 전체 어플리케이션에서 어떠한 '변수'를 전역적으로 (모든 클래스에) 선언을 하고 이 곳 저 곳에서 사용을 하기 편리하도록 하기 위해 사용됩니다. 코코아 프로그램 환경에서 실제적으로 쓰이는 전역변수에 대해 알아보면, 이는 C 언어에서의 전역변수와 같은 모양새는 아니지만, 코코아 프로그램에서는 전형적인 전역변수의 형태를 띄고 있습니다. 전 시간에 공부한 Appdelegate도 전역변수의 형태를 띄고 있습니다. Appdelegate 는 초기에 프로젝트를 선언할 경우 만들어집니다.
이 Appdelegate에 전역변수를 놓고 사용을 할 수도 있지만, 이는 anti-pattern 이라고 하는군요. 객체지향에서 구조화를 시키는 과정에서 문제가 발생하는데, Appdelegate는 the Appdelegate와 관련있는 것만 연결이 되어야 하지, 다른 객체와 관련된 것을 AppDelegate안에 저장을 한다면 객체가 가지고 있어야 하는 것을 훔치는 것과 마찬가지라고 합니다.
실무적인 측면에서 객체를 지향한다면, Appdelegate가 수백줄 수천줄이 되도록 몰아넣는 것이 아니라 위 언급처럼 실제 Appdelegate가 정상적으로 수행해야 하는 것들을 포함하고 그 외에는 각 클래스에서 담당해야 한다는 의미로 해석됩니다 ( 클래스는 많고 세분화되어 있을 수록 좋습니다! )
디자인이 잘ㄷ 된 프로그램은 각자의 클래스를 구성해서 모든 클래스들이 별도로 존재하는 독립체가 되게 하여야 합니다 Appdelegate 에게 모든 것을 떠넘기는 것은 위 같은 개념을 위반한다고 볼 수 있습니다.
Singleton in Cocoa
캡슐화의 문제점에 대한 해결책은 전역 데이터를 하나의 별도 모듈로 다룰 수 있는 클래스를 제작하는 것입니다. 이러한 방법은 싱글턴을 통해 가능합니다. *참고 : https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32 (영어좀 공부해야겠습니다@.@)
즉 아래의 코드와 같이 Sington 클래스를 제작 후 전역변수 사용히 따로 만들어진 이 클래스를 참조하여 사용을 한다는 의미입니다. 전역변수 들을 한 클래스에 구현해 놓고 만드는 것이 '싱글턴'으로 이해가 가네요.(혹시 틀렸으면 댓글 부탁드립니다.)
정확한 사용 예제는 추후 고수분들께 여쭤보고 한번 간단하게 제작한 후 올리도록 하겠습니다.
SYNTHESIZE_SINGLETON_FOR_CLASS(MyClassName);
+ ( MyClassName *)sharedMyClassName;
[ MyClassName sharedMyClassName ];
|
The solution to the encapsulation problem is to create classes that manage any global data as discreet modules. This is done through a singleton.
The basic recipe for making a singleton is given by Apple: Creating a Singleton Instance.
I personally like to put these singleton methods into a macro, which you can download in mySynthesizeSingleton.h file. If you #import!
this header at the top of a class implementation, then all you need to do is write:
SYNTHESIZE_SINGLETON_FOR_CLASS(MyClassName); |
inside the @implementation MyClassName
declaration and your class will become a singleton. You will also need to add the line:
+ ( MyClassName *)sharedMyClassName; |
to the header file for MyClassName
so the singleton accessor method can be found from other source files if they #import!
the header.
Once your class is a singleton, you can access the instance of it using the line:
[ MyClassName sharedMyClassName ]; |
Note: A singleton does not need to be explicitly allocated or initialized (thealloc
andinit
methods will be called automatically on first access) but you can still implement the defaultinit
method if you want to perform initialization.
Advantages of a singleton
A well-designed singleton is a discrete, self-managing object that manages a specific role within your program.
Where variables hung off the Application delegate may have nothing in common with the delegate object itself, a singleton should be entirely focussed on its own specific role and responsibilities.
Search the Mac OS X 10.5 Reference in XCode for methods that begin with "shared" to see the ways in which Apple use singletons to create "manager" objects which allow you to get, set and manipulate entities that exist only once in a program.
Also, since the singleton is accessed through a method, there is some abstraction around the specific implementation — you could move from a true singleton to a per-thread based implementation if you needed, without changing the external interface.
Conclusion
Don't use globals unless you need to do so. An overwhelming majority of the data in your program has a sensible parent that is not the top-level. Singletons and top-level data should be used only when the data they contain truly belongs at the top level.
Cocoa singletons are flexible and useful when you need them. Using your application delegate to hold top-level data will work but try to limit its responsibilities to MainMenu.xib allocated objects where possible.
'옛글 > 아이폰 프로그래밍' 카테고리의 다른 글
[iOS프로그래밍] 외부 프레임워크(framework) 추가하기 (0) | 2012.05.06 |
---|---|
[iOS프로그래밍] Protocol ? (1) | 2012.05.06 |
[iOS프로그래밍] 객체의 생성과 해제 (1) | 2012.05.03 |
[iOS프로그래밍] 가로모드, 세로모드 고정시키기 (0) | 2012.05.03 |
[iOS프로그래밍] NSDictionary를 파헤쳐보자 (1) | 2012.05.03 |