为什么NSDate类型的变量不会在初始化器中初始化?

时间:2015-06-05 07:45:57

标签: ios objective-c

我正在尝试使用NSDate NSString参数在初始化中初始化NSDateFormatter变量,因此我得到null。有什么问题?
谢谢!
对不起我的英语不好。

@interface NewsEntity ()

@property (strong, nonatomic) NSString *newsSource;
@property (strong, nonatomic) NSString *newsTitle;
@property (strong, nonatomic) NSString *newsDescription;
@property (strong, nonatomic) NSURL *imageUrl;
@property (strong, nonatomic) NSDate *pubDate;

@end

@implementation NewsEntity

- (instancetype)initWithNewsSource:(NSString *)newsSource withNewsTitle:(NSString *)newsTitle withNewsDescription:(NSString *)newsDescription withImgeUrl:(NSURL *)imageUrl withPubDateString:(NSString *)pubDateString {
    self = [super init];
    if (self) {
        _newsSource = newsSource;
        _newsTitle = newsTitle;
        _newsDescription = newsDescription;
        _imageUrl = imageUrl;

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"];
        _pubDate = [dateFormatter dateFromString:pubDateString];

        NSLog(@"Date: %@", _pubDate);
        NSLog(@"Date string: %@", pubDateString);

    }
    return self;
}

@end
@interface NewsData ()

@property (strong, nonatomic) NSArray *dataSources;
@property (atomic) NSUInteger parsingFromDataSourcesComplete;
@property (strong, atomic) NSMutableArray *listOfNewsEntities;
@property (strong, nonatomic) NSMutableString *newsTitle;
@property (strong, nonatomic) NSMutableString *newsDescription;
@property (strong, nonatomic) NSString *imageUrlString;
@property (strong, nonatomic) NSMutableString *pubDate;
@property (strong, nonatomic) NSString *element;

@end

@implementation NewsData

- (instancetype)init {
    self = [super init];
    if (self) {
        _dataSources = @[FIRST_SOURCE_URL, SECOND_SOURCE_URL];
    }
    return self;
}

- (void)getNewsData {
    for (NSString *dataSource in self.dataSources) {
        self.listOfNewsEntities = [[NSMutableArray alloc] init];
        NSURL *url = [NSURL URLWithString:dataSource];
        NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
        [xmlParser setDelegate:self];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [xmlParser parse];
        });
    }
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    self.element = elementName;

    if ([self.element isEqualToString:@"item"]) {
        self.newsTitle = [[NSMutableString alloc] init];
        self.newsDescription = [[NSMutableString alloc] init];
        self.pubDate = [[NSMutableString alloc] init];
        self.imageUrlString = nil;
    }

    if ([elementName isEqualToString:@"enclosure"]) {
        self.imageUrlString = [attributeDict objectForKey:@"url"];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if ([self.element isEqualToString:@"title"]) {
        [self.newsTitle appendString:string];
    }
    else if ([self.element isEqualToString:@"description"]) {
        [self.newsDescription appendString:string];
    }
    else if ([self.element isEqualToString:@"pubDate"]) {
        [self.pubDate appendString:string];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"item"]) {

        NewsEntity *newsEntity = [[NewsEntity alloc] initWithNewsSource:nil withNewsTitle:self.newsTitle withNewsDescription:self.newsDescription withImgeUrl:[NSURL URLWithString:self.imageUrlString] withPubDateString:self.pubDate];

        [self.listOfNewsEntities addObject:newsEntity];
    }
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self prepareForSendingInfo];
    });
}

- (void)prepareForSendingInfo {
    self.parsingFromDataSourcesComplete++;
    if (self.parsingFromDataSourcesComplete == self.dataSources.count) {
        [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_NEWS_INFO_IS_READY object:self.listOfNewsEntities];
    }
}

@end

输出示例:

2015-06-04 18:21:34.384 TestAssignmentR[70762:12799790] Date: (null)  

2015-06-04 18:21:34.384 TestAssignmentR[70762:12799790] Date string: Thu, 04 Jun 2015 18:07:56 +0300  

2015-06-04 18:21:34.385 TestAssignmentR[70762:12799790] Date: (null)  

2015-06-04 18:21:34.385 TestAssignmentR[70762:12799790] Date string: Thu, 04 Jun 2015 18:05:56 +0300  

2015-06-04 18:21:34.386 TestAssignmentR[70762:12799790] Date: (null)  

2015-06-04 18:21:34.386 TestAssignmentR[70762:12799790] Date string: Thu, 04 Jun 2015 18:05:17 +0300  

UPD:

我已经改变了dateFormatter,但是没有帮助 问题必须在NewsData类的某个地方 我也试过这个例子,它工作正常:

@interface TestDateFormatter ()

@property (strong, nonatomic) NSDate *date;

@end

@implementation TestDateFormatter

- (instancetype)initWithDateString:(NSString *)dateString {
    self = [super init];
    if (self) {
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss Z"];
        _date = [dateFormatter dateFromString:dateString];
        NSLog(@"%@", dateString);
        NSLog(@"%@", _date);
    }
    return self;
}

@end

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *dateString = @"Wed, 03 Jun 2015 13:17:00 +0300";
    TestDateFormatter *test = [[TestDateFormatter alloc] initWithDateString:dateString];
}

@end

3 个答案:

答案 0 :(得分:1)

日期格式说明符不正确。您希望ZZZ获得时区偏移量:

@"EEE, dd MMM yyyy HH:mm:ss ZZZ"
                            ^^^

另外我认为在init方法中进行这种格式转换是相当不寻常的。传入已经初始化的NSDate对象会更加灵活,然后init方法不需要假设用于表示字符串中日期的格式。这可以留给来电者。

答案 1 :(得分:1)

您可以通过其他方式检查日期格式字符串。只需使用您的格式打印当前日期,您就会看到输入字符串应该如何显示

您在时区格式方面遇到问题,应该只是Z:

NSString *pubDateString = @"Thu, 04 Jun 2015 18:05:17 +0300";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"];
NSDate *pubDate = [dateFormatter dateFromString:pubDateString];
NSString *nowDateStringValue = [dateFormatter stringFromDate:[NSDate date]];

NSLog(@"Date: %@", pubDate);
NSLog(@"Date string: %@", pubDateString);
NSLog(@"Now: %@", nowDateStringValue);




2015-06-05 10:56:55.443 Test[19514:4492358] Date: 2015-06-04 15:05:17 +0000
2015-06-05 10:56:55.443 Test[19514:4492358] Date string: Thu, 04 Jun 2015 18:05:17 +0300
2015-06-05 10:56:55.444 Test[19514:4492358] Now: Fri, 05 Jun 2015 10:56:55 GMT+3

答案 2 :(得分:1)

实际上,您的日期格式化程序字符串与您提供的日期字符串不匹配。您应该尝试使用以下日期格式化字符串:

@"EEE, dd MMM yyyy HH:mm:ss Z"

它使用Z代替zzz并返回正确的结果:

  

日期:2015-06-04 15:07:56 +0000
  日期字符串:星期四,2015年6月4日18:07:56 +0300

查看Unicode Locale Data Markup Language所有可能的日期模式以及它们匹配的信息类型

  

Z,ZZ和ZZZ:带有小时,分钟和可选秒字段的ISO8601基本格式。格式等同于RFC 822区域格式(当没有可选的秒字段时)。这相当于“xxxx”说明符。

在您的情况下,一个Z会匹配-0800+0300等时区 - 正是您想要的。