私はフィード リーダーに取り組んでおり、nsxmlparser を使用して RSS フィードを解析しています。CDATA ブロックから取得しているサムネイル オブジェクトもあります。
-(void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *someString = [[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
NSString *storyImageURL = [self getFirstImageUrl:someString];
NSURL *tempURL = [NSURL URLWithString:storyImageURL];
NSData *tempData = [NSData dataWithContentsOfURL:tempURL];
thumbnail = [UIImage imageWithData:tempData];
});
}
アーカイブおよびエンコードとデコードのメソッドを使用して、画像やその他のテーブルビュー オブジェクトを永続化しています。
問題は、上記のコードをそのまま使用すると、画像が保持されず、タイトルや公開日などの他のテーブルビュー オブジェクトが保持されることです。しかし、dispatch_async を使用せずに上記のコードを使用すると、イメージの永続化が開始されますが、ユーザー インターフェイスがロックされます。
ユーザー インターフェイスをロックせずに画像を保持するにはどうすればよいですか?
画像を保存およびキャッシュするためのライブラリや、Apple の遅延読み込みの例については回答しないでください。ありがとう
アップデート:
提供された回答に基づいて、iTunes でマルチスレッドに関するスタンフォードの講義を見た後、上記のコードを次のように実装しました。
NSString *someString = [[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
NSString *storyImageURL = [self getFirstImageUrl:someString];
NSURL *tempURL = [NSURL URLWithString:storyImageURL];
dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *tempData = [NSData dataWithContentsOfURL:tempURL];
dispatch_async(dispatch_get_main_queue(), ^{
thumbnail = [UIImage imageWithData:tempData];
});
});
}
論理的には、すべてが正しいものになりましたが、それでも機能しませんでした。この問題を解決する方法はすべてブロックされています。
アップデート:
Model View Controller Store アプローチを使用しており、ストアと接続コードは別のファイルで定義されています。以下は、NSKeyedArchiver を使用しているコードです。
- (FeedChannel *) FeedFetcherWithCompletion:(void (^)(FeedChannel *, NSError *))block {
NSURL *url = [NSURL URLWithString:@"http://techcrunch.com/feed/"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
FeedChannel *channel = [[FeedChannel alloc] init];
TheConnection *connection = [[TheConnection alloc] initWithRequest:req];
NSString *pathOfCache = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
pathOfCache = [pathOfCache stringByAppendingPathComponent:@"check.archive"];
FeedChannel *channelCache = [NSKeyedUnarchiver unarchiveObjectWithFile:pathOfCache];
if (!channelCachel) {
channelCache = [[FeedChannel alloc] init];
}
FeedChannel *channelCopy = [channelCache copy];
[connection setCompletionBlock:^(FeedChannel *obj, NSError *err) {
if (!err) {
[channelCopy addItemsFromChannel:obj];
[NSKeyedArchiver archiveRootObject:channelCopy toFile:pathOfCache];
}
block(channelCopy, err);
}];
[connection setXmlObject:channel];
[connection start];
return channelCache;
}
以下は私のエンコードとデコードの方法です。
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:title forKey:@"title"];
[aCoder encodeObject:link forKey:@"link"];
[aCoder encodeObject:creator forKey:@"creator"];
[aCoder encodeObject:pubDate forKey:@"pubDate"];
[aCoder encodeObject:thumbnail forKey:@"thumbnail"];
//[aCoder encodeObject:UIImagePNGRepresentation(thumbnail) forKey:@"thumbnail"];
[aCoder encodeObject:publicationDate forKey:@"publicationDate"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self)
{
[self setTitle:[aDecoder decodeObjectForKey:@"title"]];
[self setLink:[aDecoder decodeObjectForKey:@"link"]];
[self setCreator:[aDecoder decodeObjectForKey:@"creator"]];
[self setPubDate:[aDecoder decodeObjectForKey:@"pubDate"]];
[self setThumbnail:[aDecoder decodeObjectForKey:@"thumbnail"]];
//[self setThumbnail:[UIImage imageWithData:[aDecoder decodeObjectForKey:@"thumbnail"]]];
[self setPublicationDate:[aDecoder decodeObjectForKey:@"publicationDate"]];
}
return self;
}
答えに基づいて、画像を永続化するために追加のコードを使用する必要があるかどうかわかりません。タイトル、作成者などの他のオブジェクトが正確に永続化されているためです。