2013-11-25 61 views
0

我正在載入Facebook圖像。我正在嘗試使用下面的代碼來返回一個圖像,以便我可以使用Core Data將其保存到「朋友」對象的記錄中。它不工作..沒有得到回報。有沒有辦法在後臺加載數據,然後在主隊列上創建圖像並返回?我需要在主隊列上創建圖像,因爲我想用我的應用程序委託的託管對象上下文將其保存到我的對象中。在後臺載入Facebook圖片以保存在主線下的核心數據

+ (UIImage *)imageForObject:(NSString *)objectID { 

    NSString *url = [[NSString alloc] initWithFormat:@"https://graph.facebook.com/%@/picture?width=%d&height=%d",objectID,IMAGE_MAXWIDTH,IMAGE_MAXHEIGHT]; 
    __block UIImage *image; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      image = [[UIImage alloc] initWithData:data]; 
     }); 
    }); 
    return image; 
} 

回答

1

當然,可以在後臺加載圖片,但不是這樣。這種方法的設計使它真的不可能對而不是返回零。當您致電dispatch_async時,它立即返回並異步完成其工作。這就是爲什麼它的名字中有「異步」的原因。在加載圖像之前,您的代碼已達到return image;

雖然你在正確的軌道上。通常的做法是在後臺工作完成後將其分派回主隊列。但是當這樣做時,像你這樣的方法不可能返回圖像。如果是這樣,主隊列將不得不等待,直到圖像被加載,這背離了在後臺隊列上運行的全部目的。

你應該做的卻是:

  1. 在你dispatch_async回到主隊列,你需要與image--顯示在屏幕上做力所能及的工作,或將其寫入文件,或者無論你需要如何處理圖像。
  2. 使您的方法返回void,因爲它無法將圖像直接返回給調用者。或者,如果你喜歡,使其返回BOOL來指示圖像加載是否已啓動。但它不能返回UIImage,除非你讓主隊列等待在鏡像上 - 正如我所提到的那樣,它會破壞使用後臺隊列的整個目的。
+0

謝謝湯姆,那是一個很好的答案。我實際上有一個有目的地運行的活動指示器,因爲我正在導入,並且可以讓用戶等待,因爲他們可以看到他們正在等待。我會在後臺執行此操作,但我不知道如何在後臺成功保存(尚未)。我只在整個應用程序中使用應用程序委託管理的對象上下文,我知道我必須更改。但是,除了CIMGF中基本上指向使用魔法記錄的文章之外,我找不到一個保存在背景中的好例子。每個人似乎都有不同的做法。 – SAHM

+0

我確實有一個問題 - 我發現如果傳遞正確的參數,我可以將圖像保存在dispatch_async(dispatch_get_main_queue)中。你可以確認,如果我曾經最終創建和設置圖像,它將在我的主要managedObjectContext(應用程序委託)中創建,並且保存時不會有問題嗎? – SAHM

+0

你還可以告訴我更多關於返回布爾?它什麼時候會這樣做?這似乎是可能非常有用的東西。如果我有一個活動指標正在運行,爲什麼我甚至需要在後臺執行此操作?這些斷言正在殺死我...... – SAHM