我想向UIImageView添加使用url设置图像的能力。结果我想做点什么。
[anImageView setImageWithContentAtUrl:[NSURL URLWithString:@"http://server.com/resource.png"]];
所以我创建了一个类别(下面的代码)。
NSString *kUserInfoImageViewKey = @"imageView";
NSString *kUserInfoActivityIndicatorKey = @"activityIndicator";
@implementation UIImageView (asynchronous)
#pragma mark -
- (void)setImageWithContentAtUrl:(NSURL *)imageUrl andActivityIndicator:(UIActivityIndicatorView *)activityIndicatorOrNil {
[activityIndicatorOrNil startAnimating];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:self forKey:kUserInfoImageViewKey];
[dict setValue:activityIndicatorOrNil forKey:kUserInfoActivityIndicatorKey];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:imageUrl];
request.delegate = self;
request.userInfo = dict;
[dict release];
[request startAsynchronous];
}
#pragma mark -
#pragma mark private
- (void)requestFinished:(ASIHTTPRequest *)aRequest {
// get concerned view from user info
NSDictionary *dictionary = aRequest.userInfo;
UIImageView *imageView = (UIImageView *)[dictionary valueForKey:kUserInfoImageViewKey];
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *) [dictionary valueForKey:kUserInfoActivityIndicatorKey];
[activityIndicator stopAnimating];
NSData *responseData = [aRequest responseData];
UIImage * image = [[UIImage alloc] initWithData:responseData];
imageView.image = image;
[image release];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
}
创建ASIHTTPRequest并以图像作为委托启动。我认为如果在ASIHTTPRequest返回结果之前取消分配图像会有风险。
所以,也许在setImageWithContentAtUrl中添加一个retain:并在requestFinished:和requestFailed中添加一个版本:但我不是很自信。
怎么可能做这些事情?
此致 昆汀
答案 0 :(得分:1)
昆丁
我经常使用ASIHTTPRequest进行异步调用,所以我知道你来自哪里。此外,第一次设置是一件痛苦的事,但是你知道Three20库的TTImageView(我认为是这样)已经做了你想做的事情吗?它甚至会在本地缓存图像,因此您不必每次都加载它。反正。
您的担心是正确的:ASIHTTPRequest是NSOperation对象的包装器(它实际上是一个子类),因此只要请求处于活动状态,NSOperationQueue就会保留ASIHTTPRequest。
如果您的用户更改视图(例如,在导航栏控制器上),然后取消分配您的UIImageView,则代码可能会在尝试回拨给代理时崩溃。因此,当您取消分配图像视图时,最好保留对请求的引用,然后取消它。
而不是类别,这可能是子类化更好的时候之一 - 因为你想要覆盖dealloc方法(这就是我处理这个问题的方法)。
首先,将此属性添加到您的子类:
@property (nonatomic, retain) ASIHTTPRequest *request;
然后将此行添加到您的方法中,以便您可以继续:
self.request = request;
最后,在您的ASIHTTPRequest委托方法中,销毁引用:
self.request = nil;
然后你的dealloc看起来像这样:
- (void) dealloc
{
if (self.request)
{
// Cancels the NSOperation so ASIHTTPRequest doesn't call back to this
[self.request cancel];
}
[request release];
[super dealloc]
}