NSManagedObject 속성 값에 대한 NSNull 처리
내 속성에 대한 값을 설정하고 있습니다.NSManagedObject, 이러한 값들은,NSDictionaryJSON 파일에서 올바르게 직렬화되었습니다.제 문제는, 어떤 가치가[NSNull null], 속성에 직접 할당할 수 없습니다.
fight.winnerID = [dict objectForKey:@"winner"];
이 때문에NSInvalidArgumentException
"winnerID"; desired type = NSString; given type = NSNull; value = <null>;
나는 쉽게 값을 확인할 수 있었다.[NSNull null]할당하다nil대신:
fight.winnerID = [dict objectForKey:@"winner"] == [NSNull null] ? nil : [dict objectForKey:@"winner"];
하지만 이건 우아하지 않고 설정해야 할 속성들이 많아서 지저분하다고 생각해요.
그리고 이게 더 어려워지고NSNumber속성:
fight.round = [NSNumber numberWithUnsignedInteger:[[dict valueForKey:@"round"] unsignedIntegerValue]]
그NSInvalidArgumentException현재:
[NSNull unsignedIntegerValue]: unrecognized selector sent to instance
이 경우 치료해야 합니다[dict valueForKey:@"round"]만들기 전에NSUInteger가치가 있습니다.단 한 줄의 솔루션도 사라졌습니다.
@try @catch 블록을 작성하려고 했지만 첫 번째 값이 잡히자마자 @try 블록 전체가 점프하고 다음 속성은 무시됩니다.
더 좋은 방법은 없을까?[NSNull null]아니면 전혀 다르지만 쉽게 만들 수 있을까요?
매크로로 정리하면 조금 더 쉬워질 수 있습니다.
#define NULL_TO_NIL(obj) ({ __typeof__ (obj) __obj = (obj); __obj == [NSNull null] ? nil : obj; })
그러면 이렇게 쓸 수 있어요.
fight.winnerID = NULL_TO_NIL([dict objectForKey:@"winner"]);
또는 사전을 사전 처리하고 모두 바꿀 수 있습니다.NSNull을 가지고 있다nil관리 대상 오브젝트에 넣으려고 시도하기도 전에 말이죠.
좋아요, 오늘 아침에 일어나서 좋은 해결책을 찾았어요.이건 어때?
Mutable Arrays and Dictionary 수신 옵션을 사용하여 JSON을 시리얼화합니다.
NSMutableDictionary *rootDict = [NSJSONSerialization JSONObjectWithData:_receivedData options:NSJSONReadingMutableContainers error:&error];
...
다음을 포함하는 키 세트를 가져옵니다.[NSNull null]값을 지정합니다.
NSSet *nullSet = [leafDict keysOfEntriesWithOptions:NSEnumerationConcurrent passingTest:^BOOL(id key, id obj, BOOL *stop) {
return [obj isEqual:[NSNull null]] ? YES : NO;
}];
Mutable leafDict에서 필터링된 속성을 제거합니다.
[leafDict removeObjectsForKeys:[nullSet allObjects]];
지금 당신이 전화했을 때fight.winnerID = [dict objectForKey:@"winner"];winnerID는 자동적으로(null)또는nil와는 반대로<null>또는[NSNull null].
이것과는 관계없지만, 저는 또한 이 제품을 사용하는 것이 더 낫다는 것을 깨달았습니다.NSNumberFormatterNS Number에 문자열을 해석할 때, 제가 하고 있던 방법은integerValuenero 문자열로부터, 이것은 나에게 불필요한 NSNumber를 준다.0내가 정말로 0이길 바랐을 때.
이전:
// when [leafDict valueForKey:@"round"] == nil
fight.round = [NSNumber numberWithInteger:[[leafDict valueForKey:@"round"] integerValue]]
// Result: fight.round = 0
그 후:
__autoreleasing NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
fight.round = [numberFormatter numberFromString:[leafDict valueForKey:@"round"]];
// Result: fight.round = nil
사용하기 전에 JSON 생성 사전 또는 배열에서 늘을 제거하는 몇 가지 카테고리 메서드를 작성했습니다.
@implementation NSMutableArray (StripNulls)
- (void)stripNullValues
{
for (int i = [self count] - 1; i >= 0; i--)
{
id value = [self objectAtIndex:i];
if (value == [NSNull null])
{
[self removeObjectAtIndex:i];
}
else if ([value isKindOfClass:[NSArray class]] ||
[value isKindOfClass:[NSDictionary class]])
{
if (![value respondsToSelector:@selector(setObject:forKey:)] &&
![value respondsToSelector:@selector(addObject:)])
{
value = [value mutableCopy];
[self replaceObjectAtIndex:i withObject:value];
}
[value stripNullValues];
}
}
}
@end
@implementation NSMutableDictionary (StripNulls)
- (void)stripNullValues
{
for (NSString *key in [self allKeys])
{
id value = [self objectForKey:key];
if (value == [NSNull null])
{
[self removeObjectForKey:key];
}
else if ([value isKindOfClass:[NSArray class]] ||
[value isKindOfClass:[NSDictionary class]])
{
if (![value respondsToSelector:@selector(setObject:forKey:)] &&
![value respondsToSelector:@selector(addObject:)])
{
value = [value mutableCopy];
[self setObject:value forKey:key];
}
[value stripNullValues];
}
}
}
@end
표준 JSON 구문 분석 libs에 기본적으로 이 동작이 있으면 좋을 것입니다. NSNull로 포함시키는 것보다 늘 개체를 생략하는 것이 거의 항상 null 개체를 생략하는 것이 좋습니다.
또 다른 방법은
-[NSObject setValuesForKeysWithDictionary:]
이 시나리오에서는 다음과 같이 할 수 있습니다.
[fight setValuesForKeysWithDictionary:dict];
NSKeyValueCoding.h 헤더에서는 "NSNull 값이 사전 엔트리에 의해-setValue:nil forKey:key메시지를 수신자에게 보냅니다.
유일한 단점은 사전에 있는 키를 수신기에 있는 키로 변환해야 한다는 것입니다.
dict[@"winnerID"] = dict[@"winner"];
[dict removeObjectForKey:@"winner"];
저도 같은 문제로 고민하다가 이 글을 발견하고는 조금 다른 방법으로 했습니다.카테고리만 사용 -
NSDictionary의 새 카테고리 파일을 만들고 다음 메서드를 추가합니다.
@implementation NSDictionary (SuperExtras)
- (id)objectForKey_NoNSNULL:(id)aKey
{
id result = [self objectForKey:aKey];
if(result==[NSNull null])
{
return nil;
}
return result;
}
@end
나중에 코드에서 사용하려면 NSNULL을 포함할 수 있는 속성의 경우 다음과 같이 사용합니다.
newUser.email = [loopdict objectForKey_NoNSNULL:@"email"];
바로 그거야
언급URL : https://stackoverflow.com/questions/9137920/nsnull-handling-for-nsmanagedobject-properties-values
'source' 카테고리의 다른 글
| 플러그인을 설치하기 위한 FTP 자격 증명을 요청하는 WordPress (0) | 2023.03.27 |
|---|---|
| 스프링 부트 - 비관리형 (0) | 2023.03.27 |
| 'module-name' 모듈에 대한 선언 파일을 찾을 수 없습니다.'/path/to/module-name.module'에는 암묵적으로 '임의' 유형이 있습니다. (0) | 2023.03.27 |
| oop 유전 작용이 있는 angularjs (0) | 2023.03.27 |
| @types/*가 'dependencies' 또는 'devendencies' 중 어느 쪽으로 갈지 어떻게 판단합니까? (0) | 2023.03.27 |