NSDate 的 initWithString: 返回 nil
我正在使用 Stig Brautaset 的 JSON 框架序列化一些对象,包括 NSDates(它们是不直接支持)。
我决定使用 NSDate 的描述作为日期的 JSONFragment 表示(我不关心这样做会导致精度的微小损失)。
为了扩展 Stig Brautaset 的 JSON 框架以包含 NSDates,我定义了一个类别:
@interface NSDate (NSDate_JSON) <JSONInitializer>
-(NSString *) JSONFragment;
@end
要重新创建来自 JSON 的 NSDate (和其他类),我使用以下初始值设定项定义了一个协议:
@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: 方法。
有人知道会发生什么吗?
测试用例的完整源代码可在此处获取。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当尝试将字符串转换为日期时,您应该始终使用
NSDateFormatter
,反之亦然。-initWithString:
确实存在于 Mac 上,但不存在于 iOS 上。它要求字符串的格式极其精确。使用日期格式化程序是迄今为止最好的解决方案。附带说明一下,如果 Apple 决定更改
-[NSDate description]
的格式,您的代码将会损坏。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]
.您的测试程序是:
您的
-JSONFragment
类别方法是:此方法中发生的情况是,您使用
-description
获取该日期的字符串表示形式,然后使用 JSON 表示形式使用-JSONFragment
获取该字符串。在 SBJSON 中,
-JSONFragment
将给定对象的表示形式返回为 JSON 数据。 JSON 规范要求用引号引起来的字符串。在您的程序中:repr
包含类似@"\"2011-04-29 10:20:30 -0600\""
的字符串。由于引号的原因,该字符串不是与-[NSDate initWithString:]
一起使用的有效字符串。如果将: 更改
为:
以便 SBJSON 解析该片段并返回不带引号的字符串,那么它应该可以工作。
Your test program is:
Your
-JSONFragment
category method is: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: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:
to:
so that SBJSON parses that fragment and returns a string without the quotes, it should work.
找不到
initWithString:
的原因是,除非您导入 Foundation 并且没有在此处向我们展示,否则您的代码看不到 NSDate.h,因此它不知道 <代码>initWithString:存在。Dave 关于依赖
description
并使用NSDateFormatter
的说法非常正确。description
似乎不太可能改变,但不能保证它将继续是initWithString:
的有效输入,其中 有严格的输入要求:如果您的字符串有任何不同(包括,正如已经显而易见的那样,其中包含引号),您将得到
nil
。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 thatinitWithString:
exists.Dave's quite right about relying on
description
and using anNSDateFormatter
instead. It doesn't seem likely thatdescription
will change, but there's no guarantee that it will continue to be valid input forinitWithString:
which has a strict input requirement:If your string differs in any way (including, as has become apparent, having quotes in it), you'll get
nil
.