重写 ASIHTTPRequest 的方法

发布于 2024-12-17 19:40:25 字数 2265 浏览 0 评论 0原文

我正在使用 SDK 4.0 为 iPhone 编写应用程序,需要下载、调整大小并一张一张地显示许多图像。

我尝试使用简单的 ASIHTTPRequest 来做到这一点,但这些操作结果非常昂贵。因此,我创建了继承自 ASIHTTPRequest 的子类,并尝试覆盖 requestFinished。但我对此有疑问。嗯..我需要以某种方式在我的 UIImageView 上设置该图像。我真的不知道如何正确地做到这一点。

我尝试在子类中创建 UIImage 属性,并将调整大小的图像放在那里,然后从请求中获取它。唉,这会引起问题。我正在获取EXC_BAD_ACCESS。我猜想由于并发性,该方法可能会很危险。有没有简单又安全的方法可以做到这一点?我考虑过将该图像解析为 NSData 并以某种方式通过请求响应来切换它。

编辑: JosephH:我做了你在那里写的。它对小图片很有帮助 - 我的意思是不需要调整大小的图片。所以当我添加调整大小时 - 它再次滞后。这是一些代码:

#import "BackgroundHTTPRequest.h"

@implementation BackgroundHTTPRequest
@synthesize myimg;

-(UIImage *)imageWithImage:(UIImage*)imagee scaledToSize:(CGSize)newSize
{
    // Create a bitmap context.
    UIGraphicsBeginImageContextWithOptions(newSize, YES, [UIScreen mainScreen].scale);
    [imagee drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}


- (void)requestFinished{
    NSData *responseData = [self responseData];
    UIImage *tempimg = [UIImage imageWithData:responseData];

    CGFloat ratio = tempimg.size.height / tempimg.size.width;
    CGFloat widthmax = 320;
    CGFloat heightmax = widthmax * ratio;
    myimg = [self imageWithImage:tempimg scaledToSize:CGSizeMake(widthmax, heightmax)];
    [super requestFinished];
}

- (void)dealloc{
    self.myimg = nil;
    [super dealloc];
}
@end

以及发生这种情况的一些代码:

- (IBAction)grabURLInBackground:(NSURL *)url
{
    [self.myrequest setDelegate:nil];
    [self.myrequest cancel];
    [self.myrequest release];


    self.myrequest = [[BackgroundHTTPRequest requestWithURL:url] retain];    

    [myrequest setDelegate:self];
    [myrequest startAsynchronous];

}

- (void)requestFinished:(BackgroundHTTPRequest *)request
{
    // Use when fetching binary data
    if ((NSNull *)self == [NSNull null]){
        [request clearDelegatesAndCancel];
    } else {
        if (self.image)
            self.image.image = myrequest.myimg;
    }
    self.myrequest = nil;
}

加上添加行

[self.myrequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];

没有帮助。

I'm writing app for iPhone using SDK 4.0 that needs to download, re-size and show many images one by one.

I tried to do that with a simple ASIHTTPRequest, but these operations turned out to be very expensive. So I created subclass that inherits from ASIHTTPRequest and I'm trying to override requestFinished. I have though a problem with that. Well.. I need to somehow set that image on my UIImageView. I don't really have any idea how to do that properly.

I tried to create UIImage property in my subclass and put my re-sized image there and then just take it from request. Alas, it causes problems. I'm getting EXC_BAD_ACCESS. I guess that method might be dangerous due to concurrency. Is there any easy and safe way to do that? I thought about parsing that image to NSData and somehow switch it with requests response.

EDIT: JosephH: I did what you wrote there. It helped for small pictures - I mean this which don't need to be resized. So when I added resizing - it lagged again. Here is some code:

#import "BackgroundHTTPRequest.h"

@implementation BackgroundHTTPRequest
@synthesize myimg;

-(UIImage *)imageWithImage:(UIImage*)imagee scaledToSize:(CGSize)newSize
{
    // Create a bitmap context.
    UIGraphicsBeginImageContextWithOptions(newSize, YES, [UIScreen mainScreen].scale);
    [imagee drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}


- (void)requestFinished{
    NSData *responseData = [self responseData];
    UIImage *tempimg = [UIImage imageWithData:responseData];

    CGFloat ratio = tempimg.size.height / tempimg.size.width;
    CGFloat widthmax = 320;
    CGFloat heightmax = widthmax * ratio;
    myimg = [self imageWithImage:tempimg scaledToSize:CGSizeMake(widthmax, heightmax)];
    [super requestFinished];
}

- (void)dealloc{
    self.myimg = nil;
    [super dealloc];
}
@end

And some code where it happens:

- (IBAction)grabURLInBackground:(NSURL *)url
{
    [self.myrequest setDelegate:nil];
    [self.myrequest cancel];
    [self.myrequest release];


    self.myrequest = [[BackgroundHTTPRequest requestWithURL:url] retain];    

    [myrequest setDelegate:self];
    [myrequest startAsynchronous];

}

- (void)requestFinished:(BackgroundHTTPRequest *)request
{
    // Use when fetching binary data
    if ((NSNull *)self == [NSNull null]){
        [request clearDelegatesAndCancel];
    } else {
        if (self.image)
            self.image.image = myrequest.myimg;
    }
    self.myrequest = nil;
}

Plus adding line

[self.myrequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];

Didn't help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥抱我好吗 2024-12-24 19:40:25

您可以尝试查看我在此答案中发布的代码:

它不是子类化 ASIHTTPRequest,而是子类化 UIImageView,这似乎工作得很好。

您也许可以使其以其他方式工作,但是您的 ASIHTTPRequest 必须保留对 UIImageView 的引用...但是您没有向我们展示任何代码或告诉我们它如何/在哪里崩溃,所以我看到更多那只是疯狂的猜测。

You could try looking at the code I posted in this answer instead:

How? UITableViewCell with UIImageView asynchronously loaded via ASINetworkQueue

Rather than subclassing ASIHTTPRequest, it subclasses UIImageView, which seems to work very well.

You might be able to make it work the other way, but your ASIHTTPRequest would have to retain a reference to the UIImageView... but you've not shown us any code or told us how/where it's crashing, so anything I saw more than that will just be wild speculation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文