【问题标题】:NSDate is read as NSDate and NSCFStringNSDate 被读取为 NSDate 和 NSCFString
【发布时间】:2016-01-20 06:07:00
【问题描述】:

我的后端是 Parse.com。我的用户有一组 NSDate 对象作为他们完成某些操作的时间戳。

我正在尝试读取该数组中的最后一个对象,以测试它是否在一天的前 3 个小时内完成。

我遇到的奇怪问题如下。在我的物理设备上,我加载了假定的 NSDate 对象数组,并将对象和对象类都记录到控制台。我得到以下信息:

OBJECT: 2016-01-19T01:09:18.239Z
CLASS: __NSCFString

由于它不是NSDate 对象,因此我使用格式化程序将其设为一个并进行计算。到目前为止没有崩溃。

当我在模拟器上运行相同的代码时,我得到以下信息:

OBJECT: 2016-01-20 05:50:34 +0000
CLASS: __NSDate

所以应用程序崩溃(应该如此),因为我正在尝试使用格式化程序将已经 NSDate 对象从一个字符串转换为 NSDate,但它不是。崩溃日志显示如下:

-[__NSDate length]: unrecognized selector sent to instance 0x7ffcf3f9c480

所以我想也许这些对象实际上是不同的。我去 Parse.com 并复制对象。它们是一样的:

["2015-12-20T17:47:38.134Z"]
["2016-01-20T05:50:34.253Z"]

我知道我可以检查它是 NSCFString 还是 NSDate 并相应地处理它们,但我很想知道问题是什么。任何帮助表示赞赏。一整天都在做。干杯。

编辑:在我的物理设备上再运行几次之后。一些对象将显示为NSCFString,其他对象将显示为NSDate。再次检查 Parse.com 以确保所有对象都是相同的,并且是真的。

["2016-01-20T06:07:41.435Z"]

["2016-01-20T06:07:39.454Z"]

["2016-01-20T04:53:53.419Z"]

【问题讨论】:

  • 您可以使用 isKindOfClass 来检查对象是 nsstring 还是 nsdate 并相应地检查。
  • 我想你首先检查的是值是 NSDate 对象吗?因为这里是帮助你的链接。 stackoverflow.com/a/9637407/3378413
  • 你能看看这个答案,看看这是否有帮助。我认为他们发送的对象是自定义解析对象。 stackoverflow.com/questions/33329932/…
  • 您是从 PFObject 还是 PFObject 子类访问日期?
  • @kRiZ from PFObject

标签: ios objective-c parse-platform ios-simulator nsdate


【解决方案1】:

这里有两种方法可以帮助您处理此类问题。第一个返回 NSDate 对象,第二个返回字符串日期格式。您可以使用其中之一或同时使用两者。

- (NSDate*) getDateFromObject:(id) object{
if ([object isKindOfClass:[NSDate class]]) {
    return (NSDate*)object;
}
else if ([object isKindOfClass:NSString.class]){
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSDate *date = [dateFormatter dateFromString:object];

    return date;
}
// return nil otherwise
return nil;
}

- (NSString*) getStringFromObject:(id) object{
if ([object isKindOfClass:NSString.class]) {
    return (NSString*)object;
}
else if ([object isKindOfClass:NSDate.class]){
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSString *dateString = [dateFormatter stringFromDate:object];

    return dateString;
}
// return nil otherwise
return nil;

}

【讨论】:

  • “我知道我可以检查它是 NSCFString 还是 NSDate 并相应地处理它们,但我很想知道问题是什么。”无论哪种方式,谢谢您,将使用您的代码:-)
【解决方案2】:

我在这里面临同样的问题。我的情况是我正在接收 JSON 对象数据并将其序列化为具有 NSDate 值的对象。为此,您只需使用很少的手动编码将文本作为 NSDate 而不是来自 Web 服务的普通字符串传递:

示例(显示错误):

- (void)userFromJson:(NSData *)object error:(NSError **)error {
    NSError *localError = nil;
    NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:object options:0 error:&localError];

    if (localError != nil) {
        *error = localError;
        return;
    }

    for (NSDictionary *keyDict in parsedObject) {
        for (NSString *key in keyDict) {
            if ([self respondsToSelector:NSSelectorFromString(key)]) {
                [self setValue:[keyDict valueForKey:key];
            }
        }
    }
}

正确的一个:

- (void)userFromJson:(NSData *)object error:(NSError **)error {
    NSError *localError = nil;
    NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:object options:0 error:&localError];

    if (localError != nil) {
        *error = localError;
        return;
    }

    for (NSDictionary *keyDict in parsedObject) {
        for (NSString *key in keyDict) {
            if ([self respondsToSelector:NSSelectorFromString(key)]) {
                if ([key isEqualToString:@"dateOfBirth"]) {
                    NSDateFormatter *df = [[NSDateFormatter alloc] init];
                    [df setDateFormat:@"yyyy-mm-dd"];
                    NSDate *d = [df dateFromString:[keyDict valueForKey:key]];
                    [self setValue:d forKey:key];
                }
                else {
                    [self setValue:[keyDict valueForKey:key] forKey:key];
                }
            }
        }
    }
}

现在这对我有用,但我正试图找到一种方法来不对可能的变量名进行硬编码(你知道......模块化编码)。

希望对你有所帮助。

编辑: 经过一些工作,我得出了以下解决方案:

在您的相关课程中,您必须 #import <objc/runtime.h> ... 然后您可以检查本地对象参数类型并采取相应措施:

- (void)userFromJson:(NSData *)object error:(NSError **)error {
    NSError *localError = nil;
    NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:object options:0 error:&localError];

    if (localError != nil) {
        *error = localError;
        return;
    }

    for (NSDictionary *keyDict in parsedObject) {
        for (NSString *key in keyDict) {
            if ([self respondsToSelector:NSSelectorFromString(key)]) {

                objc_property_t property = class_getProperty([self class], [key UTF8String]);

                if ([[self getClassOfProperty:property] isSubclassOfClass:[NSNumber class]]) {
                    NSScanner *scanner = [NSScanner scannerWithString:[keyDict valueForKey:key]];
                    if ([scanner scanFloat:NULL]) {
                        [self setValue:@([[keyDict valueForKey:key] floatValue]) forKey:key];
                    }
                    else if ([scanner scanInt:NULL]) {
                        [self setValue:@([[keyDict valueForKey:key] integerValue]) forKey:key];
                    }
                    else {

                    }
                }
                else if ([[self getClassOfProperty:property] isSubclassOfClass:[NSDate class]]) {
                    NSDateFormatter *df = [[NSDateFormatter alloc] init];
                    NSString *stDate = (NSString *)[keyDict valueForKey:key];
                    if ([stDate length] == 10) {
                        [df setDateFormat:@"yyyy-MM-dd"];
                    }
                    else {
                        [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                    }

                    NSDate *d = [df dateFromString:stDate];
                    [self setValue:d forKey:key];
                }
                else if ([[self getClassOfProperty:property] isSubclassOfClass:[NSString class]]) {
                    [self setValue:[keyDict valueForKey:key] forKey:key];
                }
                else if ([[self getClassOfProperty:property] isSubclassOfClass:[NSData class]]) {
                    [self setValue:[NSData dataWithBytes:[[keyDict valueForKey:key] UTF8String] length:[[keyDict valueForKey:key] length]]
                         forKey:key];
                }
                else {

                }
            }
        }
    }
}

-(Class)getClassOfProperty:(objc_property_t)property {
    NSString *objType = [NSString stringWithUTF8String:property_getAttributes(property)];
    NSUInteger start =  [objType rangeOfString:@"\""].location;
    NSUInteger end =  [objType rangeOfString:@"\","].location;
    NSRange range;
    range.location = start + 1;
    range.length = end - range.location;
    NSString *objType2 = [objType substringWithRange:range];

    return [NSClassFromString(objType2) class];
}

现在更通用,不用具体格式,可以用NSDataDetector,参考http://www.techanswering.com/question/show/converting-nsstring-to-nsdate-and-back-again

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多