2013-12-16 4 views
0

Я использую этот код, чтобы вернуть изображение:Возвращение UIImage в блок кода

- (UIImage *)loadThumbnailForImageForUser:(int)userID inFolder:(int)folderNumber withFileName:(NSString *)fileName ofSize:(NSString *)size{ 

    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"IMAGE%@%d", fileName, folderNumber]]; 

    [DropBlocks loadThumbnail:@"" ofSize:@"s" intoPath:filePath completionBlock:^(DBMetadata* metadata, NSError* error){ 

    }]; 

    UIImage *img = [UIImage imageWithContentsOfFile:filePath]; 
    return img; 
} 

изображение возвращается всегда равна нулю. Это происходит потому, что завершающий блок вызывается позже. Есть ли способ решить проблему и вернуть изображение?

+0

Вы можете использовать некоторую стороннюю структуру, такую ​​как SDWebImage (https://github.com/rs/SDWebImage) или AFNetworking (https://github.com/AFNetworking/AFNetworking), которые добавляют удобные категории в 'UIImageView' , например, '- (ничтожной) setImageWithURLRequest: (NSURLRequest *) URLRequest placeholderImage: (UIImage *) placeholderImage успех: (аннулируются (^) (NSURLRequest * запрос, NSHTTPURLResponse * ответ, UIImage * изображение)) успех неудача :(void (^) (запрос NSURLRequest *, ответ NSHTTPURLResponse *, ошибка NSError *)); ' –

ответ

2

Как я обычно справиться с этой проблемой является использование шаблона делегата:

@protocol ImageLoadingProtocol <NSObject> 

@required 
-(void) imageLoaded:(UIImage*) image; 

@end 

в изображении загрузчика заголовка:

__weak id<ImageLoadingProtocol> delegate; 
-(void) initWithDelegate:(id<ImageLoadingProtocol>) delegate; 

//or 

@property (nonatomic, weak) id<ImageLoadingProtocol> delegate 

В вашем блоке:

[DropBlocks loadThumbnail:@"" ofSize:@"s" intoPath:filePath completionBlock:^(DBMetadata* metadata, NSError* error){ 
    UIImage *img = [UIImage imageWithContentsOfFile:filePath]; 
    [_delegate imageLoaded:img]; 
}]; 

И в классе, который создает ваш загрузчик изображений:

imageLoader = [[ImageLoader alloc] initWithDelegate:self]; 

//or 

//imageLoader.delegate = self; 

Затем, когда блок закончен ваш класс получит сообщение imageLoaded: и вы должны реализовать метод, чтобы справиться с этим:

-(void) imageLoaded:(UIImage*) image 
{ 
    //Here is where your image is usable. 
} 

Вот еще одно решение с использованием блоков:

- (UIImage *)loadThumbnailForImageForUser:(int)userID inFolder:(int)folderNumber withFileName: 

-(NSString *)fileName ofSize:(NSString *)size completionBlock:(void(^)(UIImage* image)) completionBlock 
{ 
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"IMAGE%@%d", fileName, folderNumber]]; 

    [DropBlocks loadThumbnail:@"" ofSize:@"s" intoPath:filePath completionBlock:^(DBMetadata* metadata, NSError* error) 
    { 
     UIImage *img = [UIImage imageWithContentsOfFile:filePath]; 
     completionBlock(image); 
    }]; 
} 

Предостережение: Следите за проблемами синтаксиса и проблемами управления памятью, я не писал это в IDE

+0

I когда для второго метода.Приложение завершится с завершениемBlock (img); – Alessandro

+0

Чтобы позвонить, я сделал: [storeManager loadThumbnailForImageForUser: userID inFolder: folderNumber withFileName: fileName ofSize: размер completeBlock: nil]; – Alessandro

+0

Это потому, что я снова возвращаю все: + (UIImage *) loadThumbnailForImageForUser: (int) userID inFolder: (int) folderNumber withFileName: (NSString *) fileName ofSize: (NSString *) size { DropBoxManager * storeManager = [ DropBoxManager sharedInstance]; return [storeManager loadThumbnailForImageForUser: userID inFolder: folderNumber withFileName: fileName ofSize: размер завершенияBlock: nil]; } – Alessandro

0

Нет, вы не можете использовать возврат и асинхронный блок. Либо убедитесь, что изображение доступно перед вызовом, либо, и это предпочтительный вариант, добавьте блок завершения к методу и вызовите это, предоставив изображение в качестве параметра. Затем вы можете вызвать блок либо сразу, если изображение уже доступно, либо позже, когда оно становится доступным внутренним блоком.

+1

Вы ошибаетесь, когда говорите, что не можете использовать возврат и блок завершения. Вполне возможно, что метод немедленно возвращается, а затем вызывает блок завершения, когда его асинхронная задача завершается. Вариант использования должен был бы вернуть загрузочное изображение ImageView, а затем в блоке завершения запрошенное изображение передается как параметр. – atreat

+0

@ Удовлетворительно, это возможно для немного другого требования. – Wain

Смежные вопросы