2014-03-07 6 views
0

- (id)valueForKey:(NSString *)key 메서드를 확장하는 범주를 만들 수 있으며이 키의 값이 [NSNull null] 인 경우 빈 문자열 @""을 반환합니다.NSDictionary extends valueForKey 메서드

JSON의 백엔드 서버에서 가져온 일부 키에 대해 nil 값에 연결됩니다.

그래서 일부 값을 속성에 저장해야하는 경우이 값을 0으로 설정할 수 있습니다. 나는 그것이 키에 대한 값을 확인하고 나를 nil의 의도 @"" 돌아갑니다 확장자를 사용할 경우에

은 가정하자 그래서

artist.name = ad[@"artist"][@"name"]; // nil value on the right. 

전무 키에 대한 값으로이 코드를 사용합니다. 그것은 의미가 있습니다.

또는 이렇게 나는 속성이 다른되지 문자열 유형이 @"", 0 또는 nil, 또는 0.0f 경우 맞습니다 값을 반환 한 후 속성 유형을 확인하기 위해 NSManagedObject를 확장해야합니다.

+1

[NSNull null]'_is_ 컬렉션에서 nil을 나타내는 올바른 방법입니다. 그것은 그것이 무엇을위한 것입니다. 왜 이것이 문제입니까? – matt

+0

JSON 샘플을 제공 할 수 있습니까? – sage444

+0

@matt 예 [nsnull null]을 가지고 있지만 괜찮습니다. 그래서 json이 예를 들어이 줄 "date"를 반환합니다 : null –

답변

2

오히려 NSDictionary에 범주를 정의하는 대신, 당신은 NSObject에 범주를 정의하고, 거기에 변환 할 수있는 : 이제

@interface NSObject (DBNullHandling) 
-(NSString*)nullToEmpty; 
@end 

@implementation NSObject (DBNullHandling) 
-(id)nullToEmpty { 
    return (self == [NSNull null]) ? @"" : self; 
} 
@end 

이 수행 할 수

artist.name = [ad[@"artist"][@"name"] nullToEmpty]; 

ad[@"artist"][@"name"]하면 반환 [NSNull null]을 , artist.name이 지정됩니다. @""; 그렇지 않으면 ad[@"artist"][@"name"]에 의해 반환 된 값이 할당됩니다.

+0

매우 좋은 제안이긴하지만 valueForKey 메소드를 override [= "key"] [@ "key"] 대신 사용할 수 있습니까? –

+0

@MatrosovAlexander 가능하지만 대괄호는 "경로 변경"되지 않습니다 (대괄호 구문은'objectForKeyedSubscript :'메서드 사용). – dasblinkenlight

+0

null 체크를위한 메소드 호출은 비트가 많이 있습니다. –

1

의 하위 클래스를 구현하여 valueForKey:의 구현을 변경하는 대신 키가 있는지 확인하는 것이 좋습니다. 그래서 대신이 작업을 수행 할 것입니다 :

BOOL keyExistsInDictionary = [[myDict allKeys] containsObject:key]; 
id objectForKey = [myDict objectForKey:key]; 
if (nil == objectForKey && keyExistsInDictionary) objectForKey = @""; 

objectForKey:하면 반환 당신이 키가 단순히 [NSNull null]이 포함되어 있는지 keyExistsInDictionary을 확인할 수 있습니다, nil을. 이렇게하면 존재하는 키와 수정하지 않고 키를 구별 할 수 있습니다. NSDictionary.

+0

해답을 주셔서 감사합니다 키가 존재하지만 때로는이 키의 값은 null입니다. "date": null –

1

내가 수행하는 작업은 할당을 수행하기 전에 확인하는 것입니다. 삼자 운영자는이를 수행하기위한 좋은 속기 방법입니다.

artist.name = ad[@"artist"][@"name"]; 

대신, 내가

id val = ad[@"artist"][@"name"]; 
artist.name = val ? val : @""; // or val ?: @"" 

(나는 완전히 질문을 이해하지 않은 쓰기 것, 그래서 그 이상의 단계들로 확인 깨지거나 어떤 식 으로든 수정해야 할 수도 있습니다 : 당신은이 대신 전무의 [NSNull null]를 확인하지만 당신은 아이디어를 얻을 수 있습니다)

+0

예, 이전 코드에서했던 것과 동일합니다. 각 엔티티마다 10 개 정도의 많은 값이 있으므로이 경우 많은 줄을 복사합니다. –

+0

'artist.name = ad [@ "artist"] [@ "name"]? : @ "";'한 줄 –

1

내가 확장됩니다 범주 만들 수 - (ID) valueForKey :.. (있는 NSString *) 키 방법을

여기에 짧은 대답은 아니요,하지 마십시오입니다.카테고리를 사용하면 메서드를 추가하여 클래스를 확장 할 수 있지만 기존 메소드를 재정의하는 데 클래스를 사용해서는 안됩니다. 클래스의 메소드가 클래스에 추가되는 순서가 정의되어 있지 않기 때문에 동일한 메소드를 재정의하는 두 개의 카테고리가있는 경우 어떤 메소드를 사용할 지 알 수 없습니다. 클래스가 궁극적으로 결국 끝낼 메소드의 버전.

또 다른 이유는 재정의하는 메서드에서 원래 메서드를 참조 할 방법이 없기 때문에 유지하려는 동작을 다시 구현해야한다는 것입니다.

마지막으로 카테고리가 클래스를 변경하므로 해당 클래스의 모든 인스턴스에 새로운 동작이 적용됩니다. 새로운 메소드를 사용하지 않는 코드는 새로운 기능에 영향을받지 않습니다. 그러나 기존 방법을 변경하면 (특히 NSDictionary으로 널리 사용되는 클래스의 경우) 많은 기존 코드를 손상시킬 가능성이 큽니다. 이 키의 값이 동일 할 경우

는 [NSNull 널 (null)]는 빈 문자열 나를 돌아갑니다 @ ""

당신은 이미 좋은 답변을 늘어 놓던, 당신이 범주에 대한 질문 만하기 때문에, 다음은 카테고리를 적절하게 사용하여 문제를 해결하는 방법입니다. -valueForKey:을 변경하는 대신 범주를 사용하여 문자열을 반환하는 -stringForKey:이라는 새 메서드를 추가합니다. 당신이 독점적으로 문자열로 작업하는 것처럼 들리므로 이것은 합리적인 해결책처럼 보입니다. 구현시 -valueForKey:을 호출하고 문자열이 아닌 객체를 문자열로 변환 할 수 있습니다.

@interface NSDictionary (StringValue) 
- (NSString *)stringForKey:(NSString*)key; 
@end 

@implementation NSDictionary (StringValue) 
- (NSString *)stringForKey:(NSString*)key 
{ 
    id value = [self valueForKey:key]; 
    NSString *string; 
    if ([value isKindOfClass:[NSString class]]) { 
     string = (NSString*)value; 
    } 
    else if ([value isKindOfClass:[NSNull class]]) { 
     string = @""; 
    } 
    else { 
     string = [value description]; 
    } 
    return string; 
} 
@end