2010-06-16 127 views
0

问题出在这里 - 我遵循Apple延迟加载的图像示例代码来处理我的图形表。它效果很好。但是,我的懒加载图像表正在堆叠在导航控制器中,以便您可以移入和移出菜单。虽然所有这些都有效,但当我移动到一个表格后,使用“返回”按钮立即移出它,我会发生持久性崩溃。这似乎是网络连接加载内容没有被正确关闭或回拨给他们的发布代表的结果。现在,我尝试了解这一点,并仔细设置所有代表为零,并在释放菜单之前在所有打开的网络连接上调用close。但是,我仍然收到错误。此外 - 我的整个应用程序代码短贴在这篇文章中,我不能真正发布一个特定的代码片段,说明这种情况。停止延迟加载图像?

我想知道是否有人对我可能错过的任务有想法?除了关闭网络连接并将其设置为零之外,是否需要执行任何操作来关闭网络连接?另外,我对调试工具不熟悉 - 任何人都可以提出一个很好的工具来观察网络连接并查看是什么导致它们失败?

谢谢!

回答

2

你是否通过调试器(Cmd-Y)运行它?它是否停在发生事故的地方?这应该显示你在代码中发生问题的地方。我敢打赌,这个问题与过度释放某些东西有关,而不是清理连接。您是否获得EXC_BAD_ACCESS?检查任何代表并确保它们在零时--viewWillDisappear被调用。这样,如果有任何事情试图回拨给委托人,它将只是一个无操作。

您可能还想尝试启用僵尸(NSZombieEnabled),它会告诉您什么时候再次访问了已释放的对象。这对于发现过度释放的对象非常有帮助。

+0

非常感谢,这是一个非常有用的提示!那僵尸功能是非常有用的......我以前在XCode文档中提到过僵尸,但我不知道他们到现在为止做了什么。 – bigmac 2010-06-16 17:51:20

+1

格雷格,如果它是一个有用的提示你为什么不投票并接受它? – Terry 2010-06-16 19:34:30

0

如果您正在执行任何异步功能(网络请求,核心位置更新等),那么运行风险是您的视图控制器是该操作的委托时会在异步函数返回时解除分配。即退出视图并将代表目标从后台进程中移走。我已经处理了好几次。

这就是你要做的。使用ASIHTTPRequest库(无论如何你都应该这样做 - 这太棒了)。创建一个合成属性来保存您的请求。然后在viewWillDisappear,根据您的请求调用-cancel。为了安全起见,我还将其代表设置为零,但这应该是不必要的。

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

@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]; 
} 
+0

感谢异步库上的提示。我一定会为我的(不可避免的)下一个iPhone项目检查一下......我已经完成了我所有的网络活动,这次我使用Apple示例代码作为指导,并且实施了大量从我的熟悉的Flash AS3工作。它工作得很好,我学到了很多东西!然而,在未来使生活变得更加容易将会很好...... – bigmac 2010-06-16 17:59:53

+0

原则依然存在 - 在您的viewDidUnload中,您应该将NSURLRequest对象的委托设置为nil。给nil的消息是一个没有错误的无操作(这是很好的知道,如果你有一种方法,似乎什么也不做!),所以它是很好的践踏你的委托链接,所以它不会尝试回拨一个代言人,已经过时了。 – 2010-06-16 18:39:29

1

啊哈......大量的僵尸狩猎后(感谢,马特龙),我发现,这个问题在苹果的LazyTableImages示例代码中的错误造成的。这个例子提供了取消所有图像加载,我变成了一个通用的方法stopAllImageLoads以下实现...

RootViewController.mLazyTableImages示例代码:

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 

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

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

[allDownloads makeObjectsPerformSelector:@selector(cancelDownload)]; 

一旦该行被更改,其他所有内容都会落空。事实证明,我并没有打电话给我的stopAllImageLoads方法,我的意思是 - 我一度禁用了它,因为它造成了错误。一旦恢复原状,内存问题就会清除,因为在表代表发布之前,图像加载已成功取消。

谢谢大家的帮助。