NSDate's initWithString: is returning nil

眉间皱痕 提交于 2020-01-07 04:32:14

问题


I'm using Stig Brautaset's JSON framework serialize some objects, including NSDates (which are not directly supported).

I decided to use NSDate's description as the JSONFragment representation of a date (I don't care about the minor loss of precision incurred in doing so).

To extend Stig Brautaset's JSON framework to include NSDates, I defined a category:

@interface NSDate  (NSDate_JSON) <JSONInitializer>

-(NSString *) JSONFragment;

@end

To recreate an NSDate (and other classes) from JSON, I defined a protocol with the following initializer:

@protocol JSONInitializer <NSObject>

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

@end

I'm having issues with this initializer. In NSDate's case, it just calls initWithString:, and that's were I get into trouble: it always returns nil. This is the implementation:

#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

I'm not sure what's going on. Besides, the compiler warns me that the initWithString: method in initWithJSONRepresentation: could not be found.

Anybody knows what might be going on?

The full source code for a test case is available here.


回答1:


Your test program is:

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];

Your -JSONFragment category method is:

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

What’s happening in this method is that you obtain a string representation of that date using -description, and then a JSON representation of that string using -JSONFragment.

In SBJSON, -JSONFragment returns the representation of a given object as JSON data. The JSON specification requires that strings are quoted. In your program:

NSString *repr = [d1 JSONFragment];

repr contains a string like @"\"2011-04-29 10:20:30 -0600\"". Because of the quotes, that string is not a valid string to be used with -[NSDate initWithString:].

If you change:

NSString *repr = [d1 JSONFragment];

to:

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

so that SBJSON parses that fragment and returns a string without the quotes, it should work.




回答2:


You should always use an NSDateFormatter when attempting to convert a string into a date or vice versa. -initWithString: does exist on the Mac, but not on iOS. It requires the string to be in an extremely precise format. Using a date formatter is by far the superior solution.

And as a side note, your code would break if Apple ever decided to change the format of -[NSDate description].




回答3:


The reason initWithString: can't be found is that unless you're importing Foundation and didn't show us here, your code can't see NSDate.h, so it doesn't know that initWithString: exists.

Dave's quite right about relying on description and using an NSDateFormatter instead. It doesn't seem likely that description will change, but there's no guarantee that it will continue to be valid input for initWithString: which has a strict input requirement:

A string that specifies a date and time value in the international string representation format — YYYY-MM-DD HH:MM:SS ±HHMM, where ±HHMM is a time zone offset in hours and minutes from GMT (for example, “2001-03-24 10:45:32 +0600”).

You must specify all fields of the format string, including the time zone offset, which must have a plus or minus sign prefix.

If your string differs in any way (including, as has become apparent, having quotes in it), you'll get nil.



来源:https://stackoverflow.com/questions/5837777/nsdates-initwithstring-is-returning-nil

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!