2011-04-29 6 views
0

Stig Brautaset의 JSON 프레임 워크는 NSDates (직접 지원되지 않음)를 비롯한 일부 객체를 직렬화합니다.NSDate의 initWithString : nil을 반환 함

나는 NSDate의 설명을 날짜의 JSONFragment 표현으로 사용하기로 결정했다. (그렇게하는 동안 발생하는 정밀도의 작은 손실은 신경 쓰지 않는다.)

가 NSDates를 포함 Stig Brautaset의 JSON 틀을 확장, I은 카테고리 정의 :

@interface NSDate (NSDate_JSON) <JSONInitializer> 

-(NSString *) JSONFragment; 

@end 

는 JSON에서있는 NSDate (다른 종류)을 재생성을 I는 다음의 이니셜과 프로토콜을 정의 :

@protocol JSONInitializer <NSObject> 

-(id) initWithJSONRepresentation: (NSString *) aJSONRepresentation; 

@end 

이 이니셜 라이저에 문제가 있습니다. NSDate의 경우 initWithString :을 호출하기 만하면 문제가 발생합니다. 항상 nil을 반환합니다. 구현 예 :

#import "NSDate+JSON.h" 


@implementation NSDate (NSDate_JSON) 

-(NSString *) JSONFragment{ 
    NSString *strRepr = [self description]; 
    return [strRepr JSONFragment]; 
} 

-(id) initWithJSONRepresentation:(NSString *)aJSONRepresentation{ 


    return [self initWithString: aJSONRepresentation]; //returns nil! 
} 
@end 

나는 무슨 일이 일어나는지 잘 모르겠습니다. 게다가 컴파일러는 initWithJSONRepresentation의 initWithString : 메소드를 찾을 수 없다고 경고합니다.

아무도 모르게 무슨 일이 일어날 지 알고 있습니까?

테스트 케이스의 전체 소스 코드는 here입니다.

+0

'aJSONRepresentation'은 어떻게 생겼습니까? –

+0

정확히 NSDate의 설명과 같습니다. – cfischer

+2

사실, 그렇지 않습니다. –

답변

2

테스트 프로그램입니다 : 다음이 방법에 무슨 일

-(NSString *) JSONFragment{ 
    NSString *strRepr = [self description]; 
    return [strRepr JSONFragment]; 
} 

당신이 -description을 사용하여 해당 날짜의 문자열 표현을 얻을 수 있다는 것입니다, 그리고 :

NSDate *d1 = [[[NSDate alloc] init] autorelease]; 
NSString *repr = [d1 JSONFragment]; 

NSDate *dd = [[[NSDate alloc] initWithString:[d1 description]] autorelease ]; 
NSDate *d2 = [[[NSDate alloc] initWithJSONRepresentation:repr] autorelease]; 

귀하의 -JSONFragment 분류 방법은 해당 문자열의 JSON 표현은 -JSONFragment을 사용합니다.

SBJSON에서 -JSONFragment은 주어진 객체의 표현을 JSON 데이터로 반환합니다. JSON 사양에서는 문자열이 인용되어야합니다. 프로그램에서 :

NSString *repr = [d1 JSONFragment]; 

repr@"\"2011-04-29 10:20:30 -0600\"" 같은 문자열을 포함합니다. 따옴표로 인해 해당 문자열은 -[NSDate initWithString:]과 함께 사용되는 유효한 문자열이 아닙니다.

당신이 변경하는 경우 :

NSString *repr = [d1 JSONFragment]; 

에 :

NSString *repr = [[d1 JSONFragment] JSONFragmentValue]; 

그래서 SBJSON 그 조각을 구문 분석하고 따옴표없이 문자열을 반환, 그것을 작동합니다.

+0

+1 : Dave는 여전히 'description'의 출력에 의존하는 것이 좋습니다. –

+0

@ Josh 잘 모르겠습니다. '- [NSDate description]'과'- [NSDate initWithString :]'에 대한 문서는 문자열 표현에 대해 매우 구체적입니다. –

+0

참, 나는 이것에 대한 당신의 우월한 경험에 굴복 하겠지만, 만일''description''이''initWithString''에 유효한 입력이라는 문서가 없다면, 애플이 더 기꺼이 생각한다고 말하고 싶습니다. 개체를 만드는 방법보다 로깅을위한 메서드의 동작을 변경합니다. 또는, 나는 모른다,'description '은 다른 것들을 위해 사용되어야 하는가? –

3

항상은 문자열을 날짜로 또는 그 반대로 변환하려고 시도 할 때 NSDateFormatter을 사용해야합니다. -initWithString:은 Mac에 있지만 iOS에는 없습니다. 문자열이 매우 정확한 형식이어야합니다. 날짜 포맷터를 사용하는 것이 훨씬 뛰어난 솔루션입니다.

Apple이 -[NSDate description] 형식을 변경하기로 결정하면 부수적으로 코드가 깨질 수 있습니다.

+0

iOS에 해당 메서드가없고 iOS를 사용하는 경우 응용 프로그램이 중단되지 않아야합니까? – cfischer

+0

아마도 API가 아니기 때문에 문서화되지 않은 메소드에 의존해서는 안됩니다. NSDateFormatter는 여전히 정답입니다. –

1

이유를 찾을 수 없습니다. Foundation을 가져 오지 않고 여기에 표시하지 않으면 코드에 NSDate.h가 표시되지 않으므로 initWithString:이 있다는 것을 알 수 없습니다.

description에 의존하고 대신 NSDateFormatter을 사용하는 것이 좋습니다. 그것은 description이 변화 할 가능성이 보이지 않는다, 그러나 initWithString:has a strict input requirement에 대한 유효한 입력 계속 것이라는 보장은 없습니다 :

국제 문자열 표현 형식의 날짜 및 시간 값을 지정하는 문자열 - YYYY-MM-DD HH:MM:SS ±HHMM, 여기서 ±HHMM은 GMT로부터 시간과 분 단위로 오프셋 된 시간대입니다 (예 : "2001-03-24 10:45:32 +0600").

시간대 오프셋을 포함하여 형식 문자열의 모든 필드를 지정해야합니다.이 필드에는 더하기 또는 빼기 기호가 있어야합니다.

문자열이 어떤 식 으로든 (따옴표가있는 것처럼 보이는 경우) nil이되는 경우.

관련 문제