私はNSMutableArray
いくつかの画像のURLを持つものを持っています。画像のサイズは 12KB から 6MB です。クラスを使用AsycImageView
して実装しますが、大きな画像をダウンロードしてアプリケーションがクラッシュする場合、そのクラスの最大サイズに 6*1024*1024 (6MB) を指定し、時間間隔を 60.0 秒から 180.0 秒に増やしましたが、役に立ちません。「Received memory warning」というエラーが表示され、アプリがクラッシュすると自動的に接続がデバイスから削除されますが、シミュレーターではクラッシュはありません。
5 に答える
に使用GCD
しlazy loading
ます。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString *strURL = url here;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
UIImage *image = nil;
if(data)
image = [UIImage imageWithData:data];
dispatch_sync(dispatch_get_main_queue(), ^{
//now use image in image View or anywhere according to your requirement.
if(image)
yourImgView = image
});
});
を使用してこれを行うことができますmultiThreading
。ここにコードがあります
- (UIImageView *)getImageFromURL:(NSDictionary *)dict
{
#ifdef DEBUG
NSLog(@"dict:%@", dict);
#endif
UIImageView *_cellImage = nil;
_cellImage = ((UIImageView *)[dict objectForKey:@"image"]);
NSString *strURL = [dict objectForKey:@"imageurl"]);
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
#ifdef DEBUG
NSLog(@"%i", data.length);
#endif
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataFilePath = [NSString stringWithFormat:@"%@.png", [documentsDirectory stringByAppendingPathComponent:[dict objectForKey:@"imageid"]]];
if (data) // i.e. file exist on the server
{
[data writeToFile:dataFilePath atomically:YES];
_cellImage.image = [UIImage imageWithContentsOfFile:dataFilePath];
}
else // otherwise show a default image.
{
_cellImage.image = [UIImage imageNamed:@"nouser.jpg"];
}
return _cellImage;
}
そして、このメソッドを次のcellForRowAtIndexPath
ように呼び出します。
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:imageURL, @"imageurl", self.imgPhoto, @"image", imageid, @"imageid", nil];
[NSThread detachNewThreadSelector:@selector(getImageFromURL:) toTarget:self withObject:dict];
コードは複数のスレッドで画像の取得を開始し、画像をドキュメント フォルダーにローカルに保存します。また、同じ名前のイメージが既に存在する場合、イメージは再度ダウンロードされません。お役に立てれば
GCD を使用して画像を非同期にダウンロードできます。次のコードを使用します。
__block NSData *imageData;
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, NULL);
dispatch_async(myQueue, ^{
//load url image into NSData
imageData = [NSData dataWithContentsOfURL: your_image_URL];
if(imageData) {
dispatch_sync(dispatch_get_main_queue(), ^{
//convert data into image after completion
UIImage *img = [UIImage imageWithData:imageData];
//do what you want to do with your image
});
} else {
NSLog(@"image not found at %@", your_image_URL);
}
});
dispatch_release(myQueue);
詳細については、dispatch_queue_tを参照してください。
Web からのリモート イメージをサポートする UIImageView のカテゴリを提供する代替 API SDWebImageをドロップすることをお勧めします。画像が非同期にダウンロードされるまで、プレースホルダー画像を使用することもできます。使いやすく、多くの作業を節約できます
あなたの問題は、パフォーマンスの問題よりもメモリ使用量の問題のようです。
本当に画像を非同期でダウンロードしたい場合は、完全にテストされ、非常によく維持されているAFNetworkingのUIImageView カテゴリを使用することをお勧めします。
ただし、ここでは、デバイスでメモリの警告が表示されます (明らかに、Mac で実行されるシミュレータよりもはるかに少ないメモリしか保持されません)。
したがって、最初に静的アナライザーを使用します。
漏れが存在するかどうかを確認し、Leaks Instrumentを実行して追跡します。
お役に立てれば。