1

이전에이 스레드를 간단하다고 생각해서 주석을 달았습니다. 그 스레드는 여기에 있습니다 :배열에서 단일 객체에 바인딩하는 코코아

Cocoa binding to a particular item in an array controller

질문은 관련 (그리고 좀 더 완전하게 여기 설명 할 것이다) 나는 시도하고 목표 - C와 코코아를 배울 짓고 있어요 게임을. 텍사스 홀드 - em 포커처럼 생각하면 충분합니다. 하나의 서버는 게임 정보를 보유하고 가변 수의 클라이언트 (항상 둘 이상)의 입력을 관리합니다. 코코아 바인딩을 통해 IB의 어레이 컨트롤러를 사용하여 서버의 어레이에 저장된 게임의 공개 정보를 각 플레이어에게 표시합니다. 테이블에있는 다섯 개의 카드가 서버의 NSArray에 저장되고 각 클라이언트의 NSArrayController의 내용 필드에 바인딩되어 있다고 생각하십시오.

이 부분은 매력처럼 잘 작동합니다. 그러나 각 플레이어는 비공개로 유지해야하는 카드 두 장을 가지고 있습니다. 각 클라이언트는 특정 플레이어에게 처리 된 내용에 따라 다른 카드를 표시해야합니다. (정말로 일어나고있는 것은 때문에 나는 플레이어의 배열에 결합하고있어

NSArray * thePlayers, 

는 모든 카드가 같은 배열에 저장되는 상상 객체). 그래서 내 질문은 배열 컨트롤러 (또는 다른 컨트롤러가 필요합니까) 밖으로 단일 개체에 바인딩을 설정하려면 어떻게합니까? 즉, 플레이어 배열에 플레이어를 바인딩하는 방법은 무엇입니까? '

답변

1

그러나 각 플레이어는 비공개로 유지해야하는 카드가 두 장 있습니다. 각 클라이언트는 특정 플레이어에게 처리 된 내용에 따라 다른 카드를 표시해야합니다. (실제로 일어나고있는 것은 플레이어 개체의 배열에 바인딩되어 있기 때문입니다 ...

클라이언트는 표현하는 플레이어를 알고 있습니다. 인덱스가 아닌, 해당 플레이어 개체에 대한 플레이어 개체를 직접 참조해야합니다. MyPlayer *userPlayer; 같은 선수가 키보드에 앉아. 뭔가. 이것은 하나를 포함하여 모든 선수 의 배열을 유지 딜러 객체에 추가됩니다.

당신이 클라이언트 컨트롤러를 갖는, 그런 식으로 밖으로 속인하면 값이 사용자의 Player 객체 인 속성 인 경우 바인딩은 간단 해집니다. 카드보기를 userPlayer 프로의 카드 A와 카드 B에 직접 바인딩합니다 클라이언트 컨트롤러의 perty. (이것은 Chuck이 이미 답변에서 제안한 것과 본 질문에 대한 귀하의 대답에 대한 내 코멘트에서 제시 한 것입니다.)

모든 카드가 동일한 배열에 저장된다고 상상하십시오.

왜 내가 상상하고 싶습니까? 왜 플레이어는 자신의 카드를 따로 소유하지 않습니까?

OK, 딜러는 모든 카드 (즉, 데크)를 소유해야합니다. 은 (는)가 소유하고있는 플레이어와 공동 소유해야합니다. 플레이어는 딜러를 통해 카드에 액세스하지 않습니다. 각 플레이어는 자신의 카드를 직접 보유해야합니다.

플레이어와 같은 실수를 저지른 것처럼 들리지만, 한 객체가 색인을 통해 배열을 통해 다른 것을 알 수 있어야한다는 것을 생각하십시오.Bindings에서 지식을 사용하고 싶지 않을 수는 없습니다. 그렇다고해서는 안됩니다. 한 개체는 다른 을 직접 알고을 알아야합니다. 이것은 올바른 해결책 일뿐만 아니라 객체가 서로를 알 수있는 올바른 방법입니다. 모든 배열 인덱스 기반 참조는 아무런 이점도 없으므로 더 복잡합니다.

4

컨트롤러 또는 모델에서 특정 플레이어에 액세스하여 바인딩 할 속성을 설정했습니다. 배열의 특정 인덱스에있는 객체에 직접 바인드 할 수있는 방법이 없습니다.

2

특정 배열 인덱스에 바인딩하려는 경우 래퍼 개체를 만들 수 있습니다. 이 같은. 그것은 당신이 item0, item1 등과 바인딩 할 수 있습니다. 범위 검사는 없으며 어레이의 크기를 변경하면 문제가 발생하지만 아이디어를 얻을 수 있습니다.

인터페이스

@interface MyArrayBinder : NSObject { 
    NSMutableArray *array; 
} 
- (id)initWithMutableArray:(NSMutableArray *)theArray; 
- (NSMutableArray *)array; 
@end 

구현

#include <objc/runtime.h> 

static NSInteger _indexFromSelector(SEL sel) { 
    return [[NSStringFromSelector(sel) stringByTrimmingCharactersInSet:[NSCharacterSet letterCharacterSet]] integerValue]; 
} 

static void _dynamicSetItem(MyArrayBinder *self, SEL sel, id obj) { 
    [self.array replaceObjectAtIndex:_indexFromSelector(sel) withObject:obj]; 
} 

static id _dynamicItem(MyArrayBinder *self, SEL sel) { 
    return [self.array objectAtIndex:_indexFromSelector(sel)]; 
} 

@implementation MyArrayBinder 

- (id)initWithMutableArray:(NSMutableArray *)theArray { 
    self=[super init]; 
    if (self) { 
     array=theArray; 
     for(NSUInteger i=0; i<[array count]; i++) { 
      class_addMethod([self class], NSSelectorFromString([NSString stringWithFormat:@"item%lu", i]), (IMP) _dynamicItem, "@@:"); 
      class_addMethod([self class], NSSelectorFromString([NSString stringWithFormat:@"setItem%lu:", i]), (IMP) _dynamicSetItem, "[email protected]:@"); 
     }  
    } 
    return self; 
} 

- (NSMutableArray *)array { 
    return array; 
} 

@end