문제

차이점은 무엇 입니까? objectForKey 그리고 valueForKey?나는 문서에서 둘 다 찾아보았는데 둘 다 나에게는 똑같은 것 같았습니다.

도움이 되었습니까?

해결책

objectForKey: 이다 NSDictionary 방법.안 NSDictionary 다음과 유사한 컬렉션 클래스입니다. NSArray, 단, 인덱스를 사용하는 대신 키를 사용하여 항목을 구별합니다.키는 사용자가 제공하는 임의의 문자열입니다.어떤 두 객체도 동일한 키를 가질 수 없습니다. NSArray 동일한 인덱스를 가질 수 있습니다).

valueForKey: KVC 방법입니다.모든 클래스에서 작동합니다. valueForKey: 이름에 문자열을 사용하여 속성에 액세스할 수 있습니다.예를 들어, 제가 Account 속성이 있는 클래스 accountNumber, 다음을 수행할 수 있습니다.

NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];

[newAccount setAccountNumber:anAccountNUmber];

NSNumber *anotherAccountNumber = [newAccount accountNumber];

KVC를 사용하면 속성에 동적으로 액세스할 수 있습니다.

NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];

[newAccount setValue:anAccountNumber forKey:@"accountNumber"];

NSNumber *anotherAccountNumber = [newAccount valueForKey:@"accountNumber"];

그것들은 동등한 진술 세트입니다.

나는 당신이 이렇게 생각하고 있다는 것을 알고 있습니다.와, 하지만 냉소적으로요.KVC는 그다지 유용해 보이지 않습니다.실제로는 "장황한" 것처럼 보입니다.그러나 런타임에 변경하려는 경우 다른 언어에서는 훨씬 어려운 멋진 작업을 많이 수행할 수 있습니다(그러나 이는 질문의 범위를 벗어납니다).

KVC에 대해 더 자세히 알고 싶다면 특히 Google에 검색하면 많은 튜토리얼이 있습니다. 스콧 스티븐슨의 블로그.당신은 또한 확인할 수 있습니다 NSKeyValueCoding 프로토콜 참조.

도움이 되길 바랍니다.

다른 팁

당신이 할 때 valueForKey: 당신은 그것을 nsstring을 주어야합니다 objectForKey: NSObject 서브 클래스를 키로 사용할 수 있습니다. 키 값 코딩의 경우 키는 항상 문자열이기 때문입니다.

사실, 문서는 당신이주는 경우에도 valueForKey: NSString은 호출됩니다 objectForKey: 어쨌든 문자열이 an으로 시작하지 않는 한 @,이 경우 호출됩니다 [super valueForKey:], 전화 할 수 있습니다 valueForUndefinedKey: 예외가 발생할 수 있습니다.

여기에 사용해야 할 좋은 이유가 있습니다 objectForKey: 대신 가능한 곳 valueForKey: - valueForKey: 알려지지 않은 키로 던질 것입니다 NSUnknownKeyException "이 클래스는 키에 대한 주요 가치 코딩 호환이 아닙니다"라고 말합니다.

말했듯이 objectForKey: 데이터 유형입니다 :(id)aKey 반면 valueForKey: 데이터 유형입니다 :(NSString *)key.

예를 들어:

 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:@"123"],[NSNumber numberWithInteger:5], nil];

 NSLog(@"objectForKey : --- %@",[dict objectForKey:[NSNumber numberWithInteger:5]]);  
    //This will work fine and prints (    123    )  

 NSLog(@"valueForKey  : --- %@",[dict valueForKey:[NSNumber numberWithInteger:5]]); 
    //it gives warning "Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'"   ---- This will crash on runtime. 

그래서, valueForKey: 문자열 값 만 취하고 KVC 메소드 인 반면 objectForKey: 모든 유형의 객체를 취합니다.

objectForKey 같은 종류의 객체에 의해 액세스됩니다.

여기에서 포괄적 인 답변을 제공하려고 노력하겠습니다. 포인트의 대부분은 다른 답변에 나타나지만 각 답변이 불완전하고 일부는 잘못된 것을 발견했습니다.

맨 먼저, objectForKey: 이다 NSDictionary 방법 valueForKey: NSDictionary를 포함하여 KVC 불만 사항 클래스에 필요한 KVC 프로토콜 방법입니다.

또한 @dreamlax가 쓴 것처럼 문서는 다음을 암시합니다 NSDictionary 그것을 구현합니다 valueForKey: 방법 사용 그것의 objectForKey: 구현. 다시 말해 - [NSDictionary valueForKey:] 전화를 끊습니다 [NSDictionary objectForKey:].

이것은 암시합니다 valueForKey: 결코 더 빠를 수 없습니다 objectForKey: (동일한 입력 키에서) 철저한 테스트는 약 5%에서 15%의 차이를 의미합니다. 정상적인 상황에서는 차이가 무시할 수 있습니다.

다음 : KVC 프로토콜은 함께 작동합니다 NSString * 키, 따라서 valueForKey: 만 받아 들일 것입니다 NSString * (또는 하위 클래스) 키로 NSDictionary "하위 레벨"이되도록 다른 종류의 객체와 함께 작동 할 수 있습니다. objectForKey: 카피 가능 (NSCopying Protocol Compliant) 객체를 키로 허용합니다.

마지막, NSDictionary's 구현 valueForKey: KVC의 문서에 정의 된 표준 동작에서 벗어나고 NSUnknownKeyException 키의 경우 "@'로 시작하는"특별한 "키가 아니라면 일반적으로"집계 "기능 키를 의미합니다. @"@sum, @"@avg"). 대신, nsdictionary에서 키를 찾을 수 없을 때 단순히 nil을 반환합니다. objectForKey:

다음은 내 메모를 입증하고 증명하기위한 몇 가지 테스트 코드입니다.

- (void) dictionaryAccess {
    NSLog(@"Value for Z:%@", [@{@"X":@(10), @"Y":@(20)} valueForKey:@"Z"]); // prints "Value for Z:(null)"

    uint32_t testItemsCount = 1000000;
    // create huge dictionary of numbers
    NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:testItemsCount];
    for (long i=0; i<testItemsCount; ++i) {
        // make new random key value pair:
        NSString *key = [NSString stringWithFormat:@"K_%u",arc4random_uniform(testItemsCount)];
        NSNumber *value = @(arc4random_uniform(testItemsCount));
        [d setObject:value forKey:key];
    }
    // create huge set of random keys for testing.
    NSMutableArray *keys = [NSMutableArray arrayWithCapacity:testItemsCount];
    for (long i=0; i<testItemsCount; ++i) {
        NSString *key = [NSString stringWithFormat:@"K_%u",arc4random_uniform(testItemsCount)];
        [keys addObject:key];
    }

    NSDictionary *dict = [d copy];
    NSTimeInterval vtotal = 0.0, ototal = 0.0;

    NSDate *start;
    NSTimeInterval elapsed;

    for (int i = 0; i<10; i++) {

        start = [NSDate date];
        for (NSString *key in keys) {
            id value = [dict valueForKey:key];
        }
        elapsed = [[NSDate date] timeIntervalSinceDate:start];
        vtotal+=elapsed;
        NSLog (@"reading %lu values off dictionary via valueForKey took: %10.4f seconds", keys.count, elapsed);

        start = [NSDate date];
        for (NSString *key in keys) {
            id obj = [dict objectForKey:key];
        }
        elapsed = [[NSDate date] timeIntervalSinceDate:start];
        ototal+=elapsed;
        NSLog (@"reading %lu objects off dictionary via objectForKey took: %10.4f seconds", keys.count, elapsed);
    }

    NSString *slower = (vtotal > ototal) ? @"valueForKey" : @"objectForKey";
    NSString *faster = (vtotal > ototal) ? @"objectForKey" : @"valueForKey";
    NSLog (@"%@ takes %3.1f percent longer then %@", slower, 100.0 * ABS(vtotal-ototal) / MAX(ototal,vtotal), faster);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top