[ios] 다 중 에이전트 모델 의 디자인 과 실현
배경
전자상거래 류 응용 에서 카 트 의 로 컬 데이터 구 조 는 상대 적 으로 복잡 하고 카 트 는 공 유 된 구성 요소 로 다른 페이지 의 데이터 업데이트 가 인 스 턴 스 페이지 를 참조 하 는 모든 인 스 턴 스 페이지 에 동기 화 되 기 어렵 습 니 다. 디자인 에 주의 하지 않 으 면이 공 유 된 구성 요 소 는 매우 높 은 결합 도 다 중 에이전트 모델 을 만 들 기 쉬 우 며, 일상적인 개발 에서 거의 언급 되 지 않 는 개념 이지 만, 다 중 대 리 는 이러한 독특한 장면 에서 독특한 기능 을 가지 고 있다.프 록 시 를 사용 하면 중간 층 을 통 해 데이터 층 과 보기 의 결합 도 를 낮 출 수 있 고 프 록 시 는 실시 간 으로 알 릴 수 있 습 니 다.
사용 피하 기
NSNotification
이 모드 알림 데이터 업데이트alias
본 고 는 카 트 데이터 구조 라 는 구성 요 소 를 DB 라 고 가정 하고 데이터 업 데 이 트 를 받 아야 하 는 보기 구성 요 소 를
view_count
형식 으로 명명 한다. 예 를 들 어 view_1
프로 그래 밍 언어: Objective-C
설계 하 다.다 중 에이 전 트 는
DB
view_1
.. view_n
의 인 스 턴 스 를 가지 고 있어 야 한 다 는 것 을 의미 합 니 다. 데이터 가 업 데 이 트 될 때 순서대로 결 과 를 에이전트 방법 에 알 립 니 다. 이 인 스 턴 스 를 저장 하 는 배열 이 필요 합 니 다.프 록 시 인 스 턴 스 는 weak reference 가 필요 합 니 다. 그렇지 않 으 면 view 의 방출 로 DB 가 야생 지침 을 가지 고 있 습 니 다.
배열 의 weak reference 를 해결 하기 위해 저 는
NSPointerArray
을 선 택 했 습 니 다. Apple 문 서 는 다음 과 같 습 니 다.The NSPointerArray class represents a mutable collection modeled after NSArray, but can also hold nil values. nil values may be inserted or removed and contribute to the object’s count. An NSPointerArray object can also increase and decrease its count directly.
이것 은 집합 중의 대상 메모 리 를 추적 할 수 있 고 mutable 임 을 나타 낸다.
결합 도가 더 낮 고, 이 방법 이 더 통용 되 기 위해 서, 나 는 이러한 다 중 에이전트 모드 를 표시 하기 위해 독립 된 클래스 를 만 들 었 다
클래스
NSPointerArray
제 namespace 는 NVMMultidelegate
입 니 다. 마음대로 변경 할 수 있 습 니 다. 너무 신경 쓰 지 마 세 요.정의 인터페이스
#import
NS_ASSUME_NONNULL_BEGIN
@interface NVMMultiDelegate : NSObject
@property (nonatomic, readonly) NSPointerArray *delegates;
- (void)addDelegate:(id)delegate;
- (void)removeDelegate:(id)delegate;
@end
NS_ASSUME_NONNULL_END
대외 적 으로 readonly 의 delegates 만 노출 하고 delegate 를 추가 삭제 하 는 방법 입 니 다.
Init
- (instancetype)init {
if (self = [super init]) {
_delegates = [NSPointerArray weakObjectsPointerArray];
}
return self;
}
delegates 의 Ivars 를 초기 화 할 때 약 한 참조 메모리 관리 방식 으로 집합 내 지침 을 추적 하도록 지정 합 니 다.
inherited interface
대상 포인터 추가
- (void)addDelegate:(id)delegate {
[_delegates addPointer:(__bridge void*)delegate];
}
NVM
와 개념 적 으로 다른 점 은 NSArray
대상 의 지침 주 소 를 추가 해 야 한 다 는 것 이다. 비록 둘 다 지침 을 조작 하고 있 지만.따라서 대상 을 추가 할 때 포인터 유형 으로 전환 해 야 합 니 다. NSPointerArray
전환 이 매우 특색 이 있 습 니 다 __bridge
대상 포인터 제거
- (void)removeDelegate:(id)delegate {
NSUInteger index = [self indexOfDelegate:delegate];
if (index != NSNotFound) {
[_delegates removePointerAtIndex:index];
}
[_delegates compact];
}
- (NSUInteger)indexOfDelegate:(id)delegate {
for (NSUInteger i = 0; i < _delegates.count; i += 1) {
if ([_delegates pointerAtIndex:i] == (__bridge void*)delegate) {
return i;
}
}
return NSNotFound;
}
제거 하 는 것 은 조금 번 거 로 운 일이 다.
CoreFoundation
NSPointerArray
처럼 매우 편리 한 API 를 가지 고 있 지 않 기 때문이다. 이것 도 자신의 효용 으로 인 한 결과 이다.그래서 우 리 는 index of API 를 직접 써 야 한다. 다 중 에이전트 모델 의 대상 이 많 지 않다 는 것 을 감안 하여 우 리 는 일반적인 빠 른 속도 로 옮 겨 다 닐 것 이다.핵심: 이벤트 리 트 윗
Objc 의 응답 체인 에서 한 대상 이 selector 를 실행 할 수 있 는 지 여 부 를 판단 합 니 다.
NSArray
방법 은 우선 이 방법 을 복사 하여 호출 자 에 게 우리 의 다 중 에이전트 대상 이 저 장 된 delegates 배열 의 대상 에 응답 할 수 있 는 방법 을 알려 야 합 니 다.- (BOOL)respondsToSelector:(SEL)aSelector {
if ([super respondsToSelector:aSelector]) {
return YES;
}
for (id delegate in _delegates) {
if (delegate && [delegate respondsToSelector:aSelector]) {
return YES;
}
}
return NO;
}
호출 자가 호출 을 시작 할 수 있다 는 것 을 알 게 된 후, Objc 는 Runtime 시기 에 방법 서명 을 찾 으 러 갑 니 다. 이 방법 을 복사 해서 우 리 는 기본 적 인 방법 서명 을 바 꾸 어 호출 자가 delegates 대상 배열 에서 서명 하고 싶 은 방법 을 얻 을 수 있 도록 합 니 다.
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (signature) {
return signature;
}
[_delegates compact];
for (id delegate in _delegates) {
if (!delegate) {
continue;
}
signature = [delegate methodSignatureForSelector:aSelector];
if (signature) {
break;
}
}
return signature;
}
주의
respondsToSelector
. 이 방법 은 배열 안의 야생 지침 을 제거 하 는 데 도움 을 줄 수 있 습 니 다. 빠 른 속도 로 옮 겨 다 닐 때 존재 하지 않 는 대상 을 가리 키 는 주 소 를 가 져 오지 않도록 합 니 다.방법 서명 을 받 은 후에 다음 에 호출 할 것 입 니 다. 마찬가지 로 우 리 는 이 방법 을 복사 해 야 합 니 다.
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL selector = [anInvocation selector];
BOOL responded = NO;
for (id delegate in _delegates) {
if (delegate && [delegate respondsToSelector:selector]) {
[anInvocation invokeWithTarget:delegate];
responded = YES;
}
}
if (!responded) {
[self doesNotRecognizeSelector:selector];
}
}
이렇게 하면 delegates 배열 에 추 가 된 모든 응답 을 할 수 있 습 니 다. 이번 호출 에 응답 할 수 있 는 대상 이 없 으 면 selector 를 식별 하지 못 하 는 호출 이 발생 할 것 입 니 다. 이 호출 은 보통 exception 이 발생 하고 응용 프로그램 이 반 짝 이 며 그 레이스 케 일 검증 되 지 않 은 클래스 에서 crash 가 발생 하지 않 으 려 면덮어 쓰 는 게 좋 을 것 같 아 요.
[_delegates compact]
방법.쓰다
이 클래스 를 사용 할 때 property:
doesNotRecognizeSelector
만 설명 하면 됩 니 다.id 형식 이 라 고 밝 히 는 것 은 build time 에서 방법 검 사 를 통 해 확인 할 수 있 기 를 바 랍 니 다. 다 중 에이전트 방법 이 이러한 종류 에 명시 되 지 않 았 기 때 문 입 니 다.
예 를 들 어 tableview 의 delegate 와 datasouce 를
@property (nonatomic, strong) id multidelegate
방식 으로 multidelegate 에 추가 한 다음 지정 할 수 있 습 니 다.tableview.delegate = multidelegate;
tableview.dataSource = multidelegate
하면 됩 니 다. 물론 이것 은 그 용법 을 보 여 주 는 것 입 니 다. 가장 좋 은 방법 은 DB 가 여러 페이지 를 multidelegate 로 설정 하 는 것 입 니 다. DB 는 데 이 터 를 업데이트 할 때 한 번
[multidelegate addDelegate:tableViewDelegate]
이라는 모드 를 호출 하면 됩 니 다.주의 하 세 요. NSPointerArray 는 메모리 추적 역할 을 하기 때문에 성능 이 좋 지 않 습 니 다. 프로그램 설명 주기 에 있 는 대 리 를 같은 multidelegate 에 추가 하 는 것 을 추천 하지 않 습 니 다. 이 수량 은 수천 개 에 달 할 수 있 습 니 다. 바로 성능 병목 이 비교적 뚜렷 한 수량 을 나타 내 는 것 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.