0

複数の画像をダウンロードして電話に保存するアプリケーションがあります。合計で、おそらく約 20 枚の画像トップが必要になります。ユーザーが表示している画面に応じて、これらの画像を自由に取得できる必要があります。これらの画像は無期限に保存されるため、一時ディレクトリは使用したくありません。

現在、これらのメソッドを持つ Images という名前のクラスがあります

- (void) cacheImage: (NSString *) ImageURLString : (NSString *)imageName
{
    NSURL *ImageURL = [NSURL URLWithString: ImageURLString];

    // Generate a unique path to a resource representing the image you want

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex: 0];
    NSString *docFile = [docDir stringByAppendingPathComponent: imageName];

    // Check for file existence
    if(![[NSFileManager defaultManager] fileExistsAtPath: docFile])
    {
        // The file doesn't exist, we should get a copy of it

        // Fetch image
        NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];

        UIImage *image = [[UIImage alloc] initWithData: data];

        // Is it PNG or JPG/JPEG?
        // Running the image representation function writes the data from the image to a file
        if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
        {

            [UIImagePNGRepresentation(image) writeToFile: docFile atomically: YES];

        }
        else if([ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound || 
                [ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound)
        {
            [UIImageJPEGRepresentation(image, 100) writeToFile: docFile atomically: YES];
        }
    }
}

- (UIImage *) getCachedImage : (NSString *)imageName
{

    NSArray *paths = NSSearchPathForDirectoriesInDomains
    (NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString* cachedPath = [documentsDirectory stringByAppendingPathComponent:imageName];

    UIImage *image;

    // Check for a cached version
    if([[NSFileManager defaultManager] fileExistsAtPath: cachedPath])
    {
        image = [UIImage imageWithContentsOfFile: cachedPath]; // this is the cached image
    }
    else
    {
        NSLog(@"Error getting image %@", imageName);
    }

    return image;
}

-(void)getImages
{    

//example
    NSString *image1URL = @"http://test/image1.png";        
    NSString *image2URL = @"http://test/image2.png";        
    NSString *image3URL = @"http://test/image3.png";

    [self cacheImage:sLogo: @"Image1"];
    [self cacheImage:sBlankNav: @"Image2"];
    [self cacheImage:buttonLarge :@"Image3"];

}

-(void) storeImages
{
    image1 = [self getCachedImage:@"Image1"];
    image2 = [self getCachedImage:@"Image2"];
    image3 = [self getCachedImage:@"Image3"];

}

だから私はこのようなコードを使用します

Images *cache = [[Images alloc]init];
[cache storeImages];

サーバー上の画像が更新され、更新された画像を取得する必要がない限り、アプリが最初に画像の取得を開始したときに、画像の取得メソッドが 1 回呼び出されます。

コードは機能しますが、問題は、それを使用する画面に移動すると、画像が読み込まれるため、画面が読み込まれる前にわずかな遅延が発生することです。

私のアプリケーションはタブ化されたアプリケーションであるため、タブ 1 から開始し、コードを実装するタブ 2 をクリックすると、最初にロードするときにわずかに一時停止します。それほど長くは続きませんが、目立ち、非常に迷惑です。その後はすでに読み込まれているので問題ありません。ただし、ナビゲーション コントローラーを使用すると、最初の VC から 2 番目の VC に移動するたびにメソッドが再度呼び出されるため、ナビゲートするたびに遅延が発生します。

画像はそれほど大きくありません。最大のものは 68kb で、他の画像はそれよりもはるかに小さいものです。現在、私は5つの画像でテストしています。画像を保存および取得するためのより効率的な方法はありますか、それともコードに何か問題がありますか? アプリケーションが流動的でぎくしゃくしたりぎこちなくしたりしないようにするには、目立った遅延なくこれらの画像を取得できる必要があります。

前もって感謝します!!

4

2 に答える 2

1

データを同期的にダウンロードしているため、遅延があります

//  NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];

SDWebImage のようなスマート ライブラリを試してみてください。ローカル イメージ (プロキシ イメージ) を表示しながら、イメージを非同期にダウンロードできます。ちなみに、キャッシュ画像は今でも無料で入手できます。したがって、ローカルにいる場合でも、以前にダウンロードした画像をキャッチできます

https://github.com/rs/SDWebImage

持っている必要があります

于 2012-10-10T14:31:40.533 に答える
1

バックグラウンド スレッドで画像の読み込み作業を行うには、Grand Central DispatchまたはNSInvocationOperationを使用する 2 つのオプションがあります。GCD は、次の 2 つの中でよりクリーンであると考えられます。

dispatch_queue_t q = dispatch_get_global_queue(0, 0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_async(q, ^{
        //load images here
        dispatch_async(main, ^{
          // show on main thread here
        });
});
于 2012-10-10T14:34:13.687 に答える