2009-04-26 2 views
0

저는 코코아 (터치) 앱을 개발 중이며 다른 뷰와 컨트롤러간에 유지해야하는 특정 데이터 (자체 기기 정보 및 위치 목록 등)가 있습니다.싱글 톤에 대한 별칭으로 전역 변수?

나는 그것을 App Delegate에 인스턴스 변수로 저장하는 것을 고려해 보았지만 위임자를 언급하는 것은 상당히 번거롭다. (위치 배열에 액세스 할 때마다 [[[UIApplication sharedApplication] delegate] locations]을 입력 할 때마다 기쁨이 없다. 대표자를위한 일종의 별칭 (la NSApp)을 소개하지만, NSApp를 제외하고 나는 다른 코코아 애플리케이션에서 이것을 자주 보지 못했다.

[State sharedState] 대신 클래스를 _State으로 바꾸고 State라는 단일 인스턴스를 만들지 않으려 고 한 단계 더 나아가 내 싱글 톤 클래스의 별칭을 도입 할 생각이 들었습니까?

답변

0
#define FOO [[[UIApplication sharedApplication] delegate] locations] 
+0

그래, 정의는 좋은 생각입니다. 어쩌면 캐스트를 사용하여 경고를 피할 수 있습니다. – esad

1

아마 [을 locationManager sharedManager] 또는 유사한과 싱글을 주었다을 locationManager 같은 클래스를 작성합니다. 델리게이트를 통해 호출하면 캡슐화가 중단됩니다 (그리고 세 개의 객체를 통해 호출 할 수 있습니다). 심지어 NSApp 스타일 #define도이를 수정하지 않습니다.

+0

위치는 단순히 'Location'객체의 단순한 배열이므로 'LocationManager'를 도입하면 너무 많은 오버 헤드가 발생하지 않을까요? 제 말은 제 ['[LocationManager sharedManager] locations]''라고 할 수 있습니다. 아마도'[Location list]'와'[Location setList :] '를 통해 액세스 할 수있는 배열을 가지고있는 정적 변수 – esad

1

싱글 톤을 얻기 위해 메서드 호출을 사용하는 주된 목적은 싱글 톤을 느리게 준비 할 수 있도록하기 위해서입니다. 예를 들어 :

static State sharedStateInstance; 

@implementation State 
+ (id)sharedState { 
    if (!sharedStateInstance) 
     sharedStateInstance = /* Allocate instance */; 
    return sharedStateInstance; 
} 
@end 

그래서이 더 코드 이제까지 +sharedState를 호출하지 않는 경우, 어떤 자원을 만드는 지출되지 않습니다 것을 의미합니다.

또한이 코드는 나중에 다른 요구가 발생하는 경우 (예 : 스레드 당 하나의 인스턴스가 있는지 또는 모든 스레드에 대한 공유 인스턴스 (초기화를 중심으로 잠금 코드가 필요함)와 같은 경우) 한층 개선 될 수 있습니다.

1

코코아가 글로벌 Foo 객체 대신 [Foo sharedFoo]을 사용하도록 권장하는 몇 가지 이유가 있습니다.

[Foo sharedFoo]는 처음 사용할 때 자동으로 인스턴스를 생성 할 수 있습니다.

인스턴스를 대문자로 명명하는 것은 클래스처럼 보이므로 버그를 유발하므로 매우 혼란 스럽습니다. 명명의 일관성은 좋은 Objective-C의 핵심입니다. ObjC는 매우 동적이기 때문에 컴파일러는 다양한 실수로부터 자신을 보호 할 수 없습니다. 일관성있는 올바른 명명 및 자체 규율은 버그가없는 코코아로 연결됩니다.

는 병렬 :

Foo *foo = [Foo sharedFoo]; 
Foo *foo = [[[Foo alloc] init] autorelease]; 
Foo *foo = [Bar fooAtIndex:0]; 

그 세 가지 모두가 같은 프로그램에 법적 될 수있다. 싱글 톤 인스턴스가 있다고해서 다른 인스턴스가 없다는 것을 의미하지는 않습니다. NSNotificationCenter는 이것의 좋은 예입니다. 싱글 톤이지만 추가 인스턴스를 만들 수 있습니다 (그렇게해야하는 이유가 있습니다).

전역 변수를 전역 적으로 수정할 수 있습니다. sharedInstance 수 없습니다. 예를 들어 State이 클래스가 아닌 전역 변수 인 경우 State=nil은 프로그램의 모든 위치에서 사용할 수 있습니다. 이는 캡슐화를 중단하고 컴파일러가 catch 할 수없는 state=nil의 쉬운 오타입니다. State이 클래스이면 컴파일러는이 쉬운 오류를 catch 할 수 있습니다.

많은 코코아 이름 지정 규칙을 통해 매우 읽기 쉬운 코드를 권장하고 매우 동적이며 느슨하게 입력 된 환경에서 버그를 최소화합니다.Perl의 use strict처럼 우리는 우리가 가지고있는 작은 안전망을 포기하기 전에 매우 조심해야합니다.

+0

당신이 말한 모두에 동의합니다. 나는 액세스하려고 할 때마다 너무 많은 타이핑을 피하기를 원했습니다. 대의원. 그래서 #define 별칭을 사용했습니다. – esad

+1

자주 앱 위임에 액세스하는 경우 너무 많이 걸렸을 수 있습니다. 앱 위임자에 매달린 많은 것들이 다른 객체에 전달되거나 싱글 톤이어야합니다. 그런데 #define (디버거로 작업하기가 더 어려워지기 때문에)이 마음에 들지 않지만 잘 명명하는 한 항상 잘못된 것은 아닙니다. 예를 들어 #define AppDelegate [[UIApplication sharedApplication] delegate]를 사용했습니다. SharedLocations라고 불리는 FOO 정의는 아마도 괜찮을 것입니다. 즉, 코코아는 단시간에 읽기 쉽고 이해하기 쉽도록 강력하게 권장합니다. –