Метод делегата не вызывается - PullRequest
1 голос
/ 26 апреля 2011

Я делаю вспомогательный класс OpenSource (github) для асинхронной загрузки изображений (у меня были серьезные проблемы).

Однако у меня есть методы делегата, настроенные для оповещения делегата о том, что изображение закончило загрузку. Проблема в том, что метод делегата не вызывается. Я устанавливаю делегата и все такое, но не имею понятия, почему возникает проблема.

Пожалуйста, посмотрите на мой код! Я только опубликовал соответствующий код.

MKAsyncImageDownloader.h

@protocol MKAsyncImageDownloaderDelegate <NSObject>
@required
- (void)imageShouldFinishDownloading;
@end
@interface MKAsyncImageDownloader : NSObject {
    id <MKAsyncImageDownloaderDelegate> delegate;
}
- (id) initWithDelegate:(id <MKAsyncImageDownloaderDelegate>) delegat;
@property (retain, nonatomic) id <MKAsyncImageDownloaderDelegate> delegate;
@end

MKAsyncImageDownloader.m

- (id) initWithDelegate:(id<MKAsyncImageDownloaderDelegate>) delegat {
    self = [super init];
    if (self) {
        delegate = delegat;
    }
    return self;
}
- (void)imageAtURLHasDownloaded:(NSDictionary *)dict {
    [downloadedImageArray addObject:[dict objectForKey:@"image"]];
    [[self delegate] imageShouldFinishDownloading];
}

MKOperation.m Подкласс NSOperation. Я выделяю / инициализирую MKAsynImageDownloader для выполнения только селектора. Код:

- (void)start {
    UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:self.targetURL]];
    if (image) {
        NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:image, self.targetURL, nil] forKeys:[NSArray arrayWithObjects:@"image", @"url", nil]];
        MKAsyncImageDownloader *downloader = [[MKAsyncImageDownloader alloc] init];
        [downloader performSelectorOnMainThread:@selector(imageAtURLHasDownloaded:) withObject:dict waitUntilDone:YES];
        [dict release];
        [downloader release];
     }
    [image release];
}

RootViewController.h

MKAsyncImageDownloader *loader;

RootViewController.m Просто чтобы показать, как я настраиваю делегата.

 loader = [[MKAsyncImageDownloader alloc] initWithDelegate:self];

Ответы [ 2 ]

1 голос
/ 26 апреля 2011

Вы смотрели в SDWebImage?

Иногда самый простой способ решить проблему - это использовать рабочий код, который вам не нужно поддерживать ...

https://github.com/rs/SDWebImage

1 голос
/ 26 апреля 2011

В вашем start методе вы никогда не вызываете правильный метод инициализации, вы вызываете:

MKAsyncImageDownloader *downloader = [[MKAsyncImageDownloader alloc] init];

Вы должны звонить

MKAsyncImageDownloader *downloader = [[MKAsyncImageDownloader alloc] initWithDelegate:myDelegate];

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

То есть:

loader = [[MKAsyncImageDownloader alloc] initWithDelegate:self];

не делает

MKAsyncImageDownloader *downloader = [[MKAsyncImageDownloader alloc] init];

работа. Ваша MKOperation не имеет ссылки на ваш класс loader, для которого установлен делегат.

Вы заявляете:

MKOperation.m Подкласс NSOperation. Я выделяю / инициализирую MKAsynImageDownloader для выполнения только селектора.

Я думаю, вы неправильно понимаете, что вы здесь делаете. Вы создаете новый экземпляр MKAsynImageDownloader и выполняете селектор на этом экземпляре, а не на экземпляре loader, который находится в вашем RootController. Вы, вероятно, хотите, чтобы MKOperation взял объект MKAsyncImageDownloader во время его инициализации.

EDIT:

Это «загрузчик», о котором я говорю. В начале вашей MKOperation

if (image) {
    NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:image, self.targetURL, nil] forKeys:[NSArray arrayWithObjects:@"image", @"url", nil]];
    -->> MKAsyncImageDownloader *downloader = [[MKAsyncImageDownloader alloc] init];
    [downloader performSelectorOnMainThread:@selector(imageAtURLHasDownloaded:) withObject:dict waitUntilDone:YES];
    [dict release];
    [downloader release];
 }

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

...