[디자인 모델] 5. 단일 모델 (유일한 대상)
10213 단어 디자인 모드
일부 대상 은 하나만 필요 합 니 다. 예 를 들 어 스 레 드 풀 (threadpool), 캐 시 (cache), 대화 상자, 선 호 설정 과 레 지 스 트 대상, 로그 대상, 프린터, 그래 픽 카드 등 장치 의 드라이버 대상 을 처리 합 니 다.사실 이 대상 들 은 하나의 실례 만 있 으 면 여러 개의 실례 를 만 들 면 많은 문제 가 발생 할 수 있다.(정적 클래스 변수, 정적 방법 과 적당 한 접근 수정자 로 하나의 인 스 턴 스 만 존재 할 수 있 습 니 다.)
소크라테스 유도 식 대답: (헤드 퍼스트 디자인 모델 참조)
어떻게 대상 을 만 듭 니까?
new MyObject()
만약 다른 상대 가 Myobject 를 만 들 려 고 한다 면 어떻게 될까요?뉴 마 이 오 브 젝 트 다시 해도 돼 요?
네, 그럼요.
그래서 일단 한 가지 종류 가 있 으 면 우 리 는 그것 을 여러 번 실례 화 할 수 있 습 니까?
공 개 된 클래스 라면 돼 요.
그렇지 않 으 면 어떻게 될 까?
공 개 된 클래스 가 아니라면 같은 가방 안의 클래스 만 실례 화 할 수 있 지만 여러 번 실례 화 할 수 있다
이렇게 해도 돼 요?
public Myclass
{
private Myclass(){}
}
나 는 생각해 본 적 이 없 지만, 이것 은 합 법 적 인 정의 이 고, 어느 정도 일리 가 있다.
뭐 랄 까?
나 는 사유 가 함 유 된 구조 기 류 는 안 된다 고 생각한다.
또 개인 적 인 구조 기 대상 을 사용 할 수 있 습 니까?
네, Myclass 내 코드 는 이 구조 기 를 호출 할 수 있 는 유일한 코드 라 고 생각 합 니 다. 하지만 이것 은 상식 에 맞지 않 습 니 다.
WHY?
Myclass 의 인 스 턴 스 만 Myclass 의 구조 기 를 호출 할 수 있 지만, Myclass 를 실례 화 할 수 있 는 다른 클래스 가 없 기 때문에 이러한 인 스 턴 스 를 얻 을 수 없습니다.
어이, 생각 이 있어.어떻게 생각 하 세 요?
public Myclass
{
public static MyClass getInstance(){}
}
MyClass 는 정적 인 방법 이 있 습 니 다. 우 리 는 이 방법 을 이렇게 호출 할 수 있 습 니 다. MyClas. getInstance ();
왜 호출 할 때 대상 이름 이 아 닌 MyCLass 클래스 이름 을 사용 합 니까?
getInstance 는 클래스 방법 이 고 정적 인 방법 이기 때문에 클래스 이름 을 사용 해 야 합 니 다.
재 미 있 습 니 다. 이 걸 합치 면 '여부' 가 MyClass 를 초기 화 할 수 있 습 니까?
public MyClass
{
private MyClass(){}
public static Myclass getInstance()
{
return new MyClass();
}
}
물론 입 니 다.
자, 두 번 째 실례 화 대상 의 방식 을 생각해 낼 수 있 습 니까?
MyClass.getInstance();
코드 를 완성 할 수 있 습 니 다. MyClass 는 하나의 인 스 턴 스 만 생 성 되 었 습 니까?
응, 아마 괜 찮 을 거 야...
단일 모드 장점
단일 모드 단점
2. IOS 에서 의 응용
단일 모델 은
iOS
개발 에서 많이 사용 되 었 다. 많은 Foundation
, Cocoa
과 UIKit
중의 유형 은 모두 단일 모델 을 실현 했다. 예 를 들 어 응용 프로그램 자체 UIApplication
, 파일 조작 류 NSFileManager
, 정보 센터 NSNotificitonCenter
등 은 모두 우리 에 게 단일 모델 을 실현 해 주 었 고 우 리 는 사용 만 하면 된다.iOS
에서 단일 모드 를 사용 할 때 클래스 방법 을 사용 하고 클래스 방법 을 통 해 이 클래스 의 유일한 대상 을 되 돌려 줍 니 다.ios 에서 의 응용 은 주로 다음 과 같은 세 가지 방식 이 있다.
1、
static Singleton *instance = nil;
+ (Singleton *)sharedInstance
{
if (instance == nil) {
instance = [[super allocWithZone:NULL] init];
}
return instance;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedInstance] retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
이 를 통 해 정적 구성원 을 사용 하여 영구적 으로 존재 하 는 대상 을 유지 하고
alloc
방법 alloc
방법 allocWithZone:
을 덮어 쓰 고 3、
방법 을 호출 하 며 인용 기술 과 관련 된 모든 방법 을 덮어 쓰 는 것 을 볼 수 있다. 이 는 이 대상 을 소각 하지 않 게 한다.이렇게 보면 기본적으로 우리 가 필요 로 하 는 것 을 실현 한 것 처럼 보이 지만, 쓰기 가 귀 찮 고, 또 하나의 문제 가 있다. 그것 은 바로 다 중 스 레 드 문제 이다. 만약 다 중 스 레 드 에 있다 면, 이 방법 은 하나의 대상 만 생 긴 다 는 것 을 보장 할 수 없다.그래서 이런 방식 은 소개 만 할 뿐 추천 하지 않 습 니 다.2. 도입 헤더 파일
프로그래머 들 은 모두 게 으 름 을 피 우 는데, 지금 은 매크로 정 의 를 사용 하여 이 많은 일 을 해결 하 는 것 이 유행 하고, 더욱 주도면밀 하 게 고려 하 는 것 이 유행 하고 있다.
단일 예 는 다음 과 같은 인 터 페 이 스 를 포함한다. + (MyClass*) sharedInstance; + (void) purgeSharedInstance;
shared Instance 를 호출 하면 단일 예 를 만 들 고 되 돌려 줍 니 다.
PurgeShared Instance 를 호출 하면 단일 예 를 소각 합 니 다.
수 동 으로 alloc 를 호출 하 는 것 도 하나의 예 라 고 보장 할 수 있 습 니 다. 이렇게 호출 할 수 있 습 니 다.
[[MyClass alloc] initWithParam:firstParam secondParam:secondParam];
단지 shared Instance 이전에 호출 할 수 있 도록 해 야 합 니 다. 단 한 번 의 창설 기회 가 있 기 때 문 입 니 다.
다음은 매크로 쓰기 "
MyClass.h:
========================================
#import "SynthesizeSingleton.h"
@interface MyClass: SomeSuperclass
{
...
}
SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass);
@end
========================================
MyClass.m:
========================================
#import "MyClass.h"
@implementation MyClass
SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass);
...
@end
========================================
소스 라 이브 러 리 다운로드 주소
iOS
block
는 4.0 이후 GCD
와 iOS
두 가지 특성 이 GCD
개발 에 큰 편 의 를 가 져 다 주 고 개발 을 더욱 흥 미 롭 게 만 들 었 다. 그렇다면 어떻게 block
+ dispatch_once(dispatch_once_t *predicate, ^(void)block)
를 통 해 단일 모델 을 실현 할 수 있 을 까?유형 구조 체 의 지침 은 GCD
실행 이 완료 되 었 는 지 테스트 하 는 데 사 용 됩 니 다. 이 지침 이 가리 키 는 구조 체 는 전체 적 이거 나 정적 이 어야 합 니 다. 두 번 째 매개 변 수 는 반환 값 과 매개 변수 가 모두 비어 있 는 dispatch_once_t
이 고 block
체 에서 대상 의 초기 화 를 하면 됩 니 다. block
프로그램의 수명 주기 에 한 번 만 호출 될 수 있 기 때문에 다 중 스 레 드 에 도 문제 가 없 을 것 입 니 다. 이 방법 은 사용 방법:+ (Singleton *)sharedInstance
{
static Singleton *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[Singleton alloc]init];
});
return instance;
}
dispatch once 의 역할 은 실행 되 고 전체 프로그램의 성명 주기 에서 한 번 만 블록 대상 을 실행 하 는 것 입 니 다. 그야말로 하나의 예 를 들 어 생 긴 것 입 니 다. 그리고 프로그램 시작 에 초기 화 해 야 할 동작 도 있 습 니 다. 이 를 위해 한 번 만 실행 하면 이 dispatch once 에 넣 어 실행 할 수 있 습 니 다.
그 다음 에 우 리 는 이 코드 블록 이 실행 되 는 지 확인 하 는 단언 이 필요 하 다 는 것 을 보 았 다. 이 단언 의 지침 은 저장 해 야 한다. 첫 번 째 방법 에 비해 지침 을 하나 더 저장 해 야 한다.
방법 소개 에서 분명히 말 했다. 응용 프로그램 에서 전체 데이터 대상 (단일 모드) 을 초기 화 하 는 데 유용 하 다.
다 중 스 레 드 에서 동시에 호출 하면 이 함 수 는 이 block 호출 이 끝 날 때 까지 동기 화 를 기다 릴 것 입 니 다.
이 단언 의 지침 은 전역 적 으로 저장 하거나 정적 영역 에 두 어야 합 니 다. 자동 분배 영역 이나 동적 영역 에 저 장 된 단언 을 사용 하면 dispatch once 가 실행 하 는 결 과 는 예측 할 수 없습니다.
요약: 1. 이 방법 은 단일 예 나 초기 화 동작 을 만 들 때 사용 할 수 있 습 니 다. 유일 성 을 보장 합 니 다. 2. 이 방법 은 스 레 드 가 안전 하 므 로 안심 하고 과감하게 하위 스 레 드 에서 사용 하 십시오. (전 제 는 dispatch once t 입 니 다. onceToken
대상 은 전체 또는 정적 대상 이 어야 합 니 다. 이 점 은 매우 중요 합 니 다. 이 점 을 보장 하지 못 하면 이 방법 이 한 번 만 실 행 될 것 이 라 고 보장 할 수 없습니다.)
참고 블 로그:
물방울 이 돌 을 뚫 고 믿음 을 지 켜 라. --- wtlucky's Blog
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.