문제

iPhone 앱을위한 키 값 코딩으로 배열을 채우는 "올바른"방법을 해결하려고합니다. 나는 작동하는 무언가를 생각해 냈지만 상당히 해킹됩니다. 기본적으로 XML 문서를 코드 생성 모델 세트로 구문 분석하고 있습니다. XML 이이 형식이라고 가정 해 봅시다.

<foo>
    <bar>
        <item name="baz" />
        <item name="bog" />
    </bar>
</foo>

막대 요소를 나타내는 생성 된 객체에는 하위 노드에 대해 NSMutableARRAY가 정의되어 있습니다.

@interface Bar : NSObject {
    NSMutableArray *item;
}
@end

따라서 기본적으로 setValue : forkey : bar 인스턴스에서 항목 객체의 단일 인스턴스로 nsmutablearray 인스턴스를 덮어 쓰는 경우가 있습니다. 내가이 일을하기 위해 현재 한 일은 그것이 해킹되는 곳입니다. 나는 배열 인스턴스 변수의 이름을 다른 것으로 바꾸었다.

@interface Bar : NSObject {
    NSMutableArray *items;
}
@end

이로 인해 SetValue : Forkey : Miss의 기본 액세서가 발생합니다. 그런 다음이 메소드가 BAR 구현에 추가했습니다.

- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    if([key isEqualToString:@"item"]) {
        if(items == nil) {
            items = [[NSMutableArray alloc] init];
            [items retain];         
        }
        [items addObject:value];
    }
}

그리고 모든 것이 작동합니다! 그래도 더 나은 방법이 있어야한다고 확신합니다! 키 값 코딩 프로그래밍 안내서를 읽었지만 배열 액세서에게 어떻게 작동 해야하는지에 대해서는 불분명하기 때문에 무언가를 놓치고 있어야합니다. Countof : 및 Objectinatindex를 구현하려고 시도했습니다. KVC 프로그래밍 안내서가 표시되는 것처럼 보이지만 여전히 NSMutableAreRay가 항목 유형의 인스턴스로 덮어 쓰고 있습니다.

도움이 되었습니까?

해결책

배열에 KVC 속성을 사용하려면 설명서를 살펴보아야합니다. mutableArrayValueForKey:

기본적으로 수업과 함께 :

@interface Bar : NSObject {
    NSMutableArray *items;
}
@end

다른 곳에서 배열을 초기화했다고 가정하면 이러한 방법을 최소로 정의합니다.

- (void)insertObject:(id)object inItemsAtIndex:(NSUInteger)index {
    [items insertObject:object atIndex:index];
}

- (void)removeObjectFromItemsAtIndex:(NSUInteger)index {
    [items removeObjectAtIndex:index];
}

- (NSArray *)items {
    /* depending on how pedantic you want to be
       possibly return [NSArray arrayWithArray:items] */
    return items;
}

해당 메소드를 구현하면 호출 할 수 있습니다 [bar mutableArrayValueForKey:@"items"]. 반환합니다 NSMutableArray 객체를 추가하고 제거 할 수있는 프록시 객체. 해당 개체는 적절한 KVO 메시지를 생성하고 방금 정의한 메소드를 사용하여 실제 배열과 상호 작용합니다.

다른 팁

Martin이 제안한 것처럼 항목이 추가되거나 제거 될 때 배열을 직접 관찰 할 수 없습니다. 대신, 이것은 막대 객체의 "to-many"속성으로 간주되며 KVO 주장을 직접 만드는 것을 다루어야합니다. 막대에서 품목을 추가하고 제거하기 위해 이와 같은 일을 할 수 있습니다.

@interface Bar : NSObject
{
    NSMutableArray *items;
}
-(void)addItem:(id)item;
-(void)removeItem:(id)item;
@end

@implementation Bar
-(id)init
{
    if( (self = [super init]) ) {
        items = [[NSMutableArray alloc] init];
    }
    return self;
}

-(void)addItem:(id)item
{
    NSParameterAssert(item);
    NSIndexSet *iset = [NSIndexSet indexSetWithIndex:[items count]];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:iset forKey:@"items"];
    [items addObject:item];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:iset forKey:@"items"];
}

-(void)removeItem:(id)item
{
    NSParameterAssert(item);
    NSIndexSet *iset = [NSIndexSet indexSetWithIndex:[items indexForObject:item]];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:iset forKey:@"items"];
    [items removeObject:item];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:iset forKey:@"items"];
}
@end

항목을 직접 설정/교체 할 수 있기를 원한다면 직접 할 수있는 방법을 제시해야합니다. 일반적으로 나는 제안하고 NSArrayController 이런 종류의 경우 iPhone을 사용하기 때문에 기본적 으로이 기능을 직접 만들어야합니다.

글쎄, 당신이 그것에 대해 갈 수있는 두 가지 방법이 있습니다.

  1. 항목을 전달하는 바 클래스에 "항목 추가"메소드 추가
  2. KVC를 수행 할 때 전체 항목을 통과하는지 확인하십시오.

KVC를 사용하여 배열에 항목을 추가 할 수있는 방법이 없다고 생각합니다.

전화하기에 충분합니다 valueForKey:@"item" 그리고 결과는 변이 가능합니다. 그래서 당신은 다음을 말할 수 있습니다.

NSMutableArray* m = [theBar valueForKey:@"item"];
[item addObject: value];

정면을 구현하지 않는 한 다른 방법이 필요하지 않습니다 (변수 인스턴스 변수가없는 키).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top