停止延迟加载图片?

时间:2010-06-16 16:18:24

标签: iphone objective-c

这是问题 - 我跟着Apple延迟加载图像示例代码来处理我的图形表。它很棒。但是,我的延迟加载图像表正堆叠在导航控制器中,以便您可以移入和移出菜单。虽然这一切都有效,但当我进入一张桌子然后使用“后退”按钮立即将其移出时,我会遇到持续的崩溃。这似乎是网络连接加载内容未正确关闭或回调给已发布的代理的结果。现在,我已尝试完成此操作,并在释放菜单之前仔细将所有代理设置为nil并在所有打开的网络连接上调用close。但是,我仍然收到错误。另外 - 将我的整个应用程序代码发布到这篇文章中,我无法发布一个特定的代码片段来说明这种情况。

我想知道是否有人对我可能遗失的任务有想法?除了关闭网络连接并将其设置为nil之外,我是否需要执行任何操作来关闭网络连接?此外,我是调试工具的新手 - 任何人都可以建议使用一个很好的工具来观察网络连接并查看导致它们失败的原因吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

您是否通过调试器(Cmd-Y)运行它?它会停在发生碰撞的地方吗?这应该会在代码中向您显示问题。我认为这个问题与过度释放而不是清理连接有关。你有EXC_BAD_ACCESS吗?检查任何代表,并确保在调用-viewWillDisappear时它们是nil。这样,如果有任何东西试图回叫代表,它将只是一个无操作。

您可能还想尝试启用僵尸(NSZombieEnabled),它会告诉您何时再次访问已释放的对象。它对于找到过度释放的对象非常有帮助。

答案 1 :(得分:1)

啊哈...在大型僵尸狩猎之后(谢谢,Matt Long),我发现问题源于Apple的LazyTableImages示例代码中的错误。该示例提供了以下用于取消所有图像加载的实现,我将其转换为通用stopAllImageLoads方法...

来自RootViewController.m示例代码中的LazyTableImages

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    // terminate all pending download connections
    NSArray *allDownloads = [self.imageDownloadsInProgress allValues];
    [allDownloads performSelector:@selector(cancelDownload)];
}

在上述方法的最后一行中出现错误,其中在对象数组上调用performSelector。上面的实现调用数组本身的选择器,而不是数组中的每个对象。因此,最后一行应该是这样的:

[allDownloads makeObjectsPerformSelector:@selector(cancelDownload)];

一旦这条线改变了,其他一切都落到了位置。事实证明我没有调用我想要的stopAllImageLoads方法 - 我曾一度禁用它,因为它导致了错误。一旦恢复到位,内存问题就会被清除,因为图像加载在表委托发布之前已成功取消。

感谢大家的帮助。

答案 2 :(得分:0)

如果您正在执行任何异步功能(网络请求,核心位置更新等),则存在以下风险:作为该操作的委托的视图控制器在异步函数返回时被释放。即你退出视图并使代理目标远离后台进程。我已多次处理过这个问题。

这是你做的。使用ASIHTTPRequest库(无论如何你都应该这样做 - 它很棒)。创建合成属性以保存您的请求。然后在viewWillDisappear中,根据您的请求调用-cancel。为了安全起见,我还将其委托设置为nil,但这应该是不必要的。

这是你想要做的草图。注意我在这里键入了这个,没有语法检查它或任何东西。

@implementation MyViewController

@synthesize req //this is an ASIHTTPRequest *req.

-(void)viewDidLoad 
{
  //make an NSURL object called myURL
  self.req = [ASIHTTPRequest requestWithURL:myURL];
  self.req.delegate = self;
  [self.req startAsynchronous];
}

-(void)viewWillDisappear
{
  [self.req cancel];
}

-(void)requestFinished:(ASIHTTPRequest *)request
{
  NSString *string = [request responseString];
}