【问题标题】:Delegate method not being called未调用委托方法
【发布时间】:2011-08-12 16:39:03
【问题描述】:

我正在制作一个用于异步下载图像的 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 的子类。 我 alloc/init 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];

【问题讨论】:

  • 与您的问题没有直接关系,但您的财产保留了委托,但您的 init 分配了。通常,在与代表打交道时,“分配”是正确的答案。
  • 最后,在 imageAtURLHasDownloaded 中放一个断点,我无法想象找到问题会那么难......
  • 我发现了问题,那就是委托是零。我尝试将其更改为分配,但没有任何区别。

标签: iphone objective-c delegates nsoperation nsoperationqueue


【解决方案1】:

在您的 start 方法中,您永远不会调用正确的 init 方法,而是在调用:

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 的子类。我 alloc/init MKAsynImageDownloader 只执行选择器。

我想你误解了你在这里做什么。您将创建一个全新的 MKAsynImageDownloader 实例并在 那个 实例上执行选择器,而不是在您的 RootController 中的 loader 实例。您可能希望 MKOperation 在它初始化期间采用 MKAsyncImageDownloader 对象。

编辑:

这就是我所说的“下载器”。在您的 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 中的实例分开的实例,这个实例没有委托集。这是您正在处理的那个,因此,这个是试图通知委托的那个……但同样,它没有有一个委托集。

【讨论】:

  • MKOperation,NSOperation 子类,虽然不需要成为委托。下载图像后,MKOperation 文件无需更改任何内容。 RootViewController 是唯一需要设置为委托的类。
  • 但是 MKOperation 是完成工作的地方!您创建另一个实例,该实例没有委托集。
  • 在 MKOperation 中调用了委托方法,但是我需要在 RootViewController 中调用它,因为 tableView 需要更新。
  • loader != 下载器,我不知道还能告诉你什么。
  • loader.class != downloader.class!!! loader在RootViewController.h中,downloader在MKOperation、NSOperation子类中。
【解决方案2】:

你看过 SDWebImage 吗?

有时解决问题最简单的方法是使用无需维护的工作代码...

https://github.com/rs/SDWebImage

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2016-07-16
    • 2019-01-04
    • 2014-02-07
    相关资源
    最近更新 更多