Iphone ASIHTTPRESS dealloc和EXC\u BAD\u访问问题
我正在使用一组ASIHTTPRequest包装器(AsyncImageLoader)在UITableView中下载单元格的图像 我在处理ASIHTTPRequests时遇到问题。如果我释放它们,如果我在它们试图加载图像时不断上下滚动,我最终会有一个EXC_BAD_访问权限 这是我的包装纸的样子Iphone ASIHTTPRESS dealloc和EXC\u BAD\u访问问题,iphone,objective-c,exc-bad-access,asihttprequest,dealloc,Iphone,Objective C,Exc Bad Access,Asihttprequest,Dealloc,我正在使用一组ASIHTTPRequest包装器(AsyncImageLoader)在UITableView中下载单元格的图像 我在处理ASIHTTPRequests时遇到问题。如果我释放它们,如果我在它们试图加载图像时不断上下滚动,我最终会有一个EXC_BAD_访问权限 这是我的包装纸的样子self.request具有retain属性,targetCell是我要将图像放入的单元格: @implementation AsyncImageLoader - (void)loadImageFromUR
self.request
具有retain属性,targetCell
是我要将图像放入的单元格:
@implementation AsyncImageLoader
- (void)loadImageFromURL:(NSString*)fileName target:(ResultTableViewCell*)targetCell {
// check for cached images, etc
NSURL* url = [NSURL URLWithString:fileName];
[self.request cancel];
self.request = [ASIHTTPRequest requestWithURL:url];
self.request.delegate = self;
}
- (void)startLoading {
[self.request startAsynchronous];
}
- (void)cancel {
[self.request cancel];
self.request = nil;
}
- (void)requestFinished:(ASIHTTPRequest*)requestDone {
// cache image, set cell image...
self.request = nil;
}
- (void)requestFailed:(ASIHTTPRequest*)requestDone {
// handle answer as well
self.request = nil;
}
@end
indexath.row%6
th AsyncImageLoader在CellForRowatineXpath
中调用了loadImageFromURL
,因此如果我一直上下滚动,它会使用同一个对象一次又一次地调用,取消请求,因为它们还没有结束
但我总是有一个很糟糕的机会。根据调用堆栈,它发生在ASIHTTPRequest的markAsFinished
中,由failWithError
调用,由[self.request cancel]
在loadImageFromURL:
中调用。大多数时候ASIHTTPRequest已经发布了(我在它的dealloc中添加了一个NSLog),但我不知道这是怎么可能的,因为ASIHTTPRequest似乎抛出了保留,所以在取消时它不会被释放
如果我删除委托方法中的self.request=nil
,我就没有任何EXC\u BAD\u访问权限,但是由于ASIHTTPRequests一直在创建而没有释放,它们最终根本不起作用
有人能告诉我我做错了什么吗?当你遇到一个问题,你获得了EXC\u BAD\u访问权限,这意味着你发布了一些内容。在大多数情况下,您只需运行调试器(Command-Y),并在堆栈跟踪崩溃时查看代码的最后一行,以确定哪个对象被过度释放。如果这不起作用,那么您需要检查并查看在释放对象后,正在再次访问哪个对象。这几乎总是为你指明正确的方向 作为补充说明,还有其他一些库可以完成您正在尝试的工作。我没怎么用过这个,但看起来它至少有潜力。签出:。也许这会给你一些想法
致以最良好的祝愿。这听起来很像我看到的撞车事故 我还不确定是什么原因导致它,但我坚信它与客户机代码无关(即,它要么在ASIHTTPRequest中,要么在操作系统中) 我已经修复了asi http请求中的一些问题,但此崩溃仍然存在 我一直在苹果论坛上寻求帮助: 以下是这次事故对我的影响:
#2 0x32c02e14 in CFRetain ()
#3 0x32c709b6 in __CFTypeCollectionRetain ()
#4 0x32c06c60 in _CFArrayReplaceValues ()
#5 0x32b0994c in -[NSCFArray insertObject:atIndex:] ()
#6 0x32b098f0 in -[NSCFArray addObject:] ()
#7 0x32b709f0 in __chooseAll ()
#8 0x32b71bde in __finishedOp ()
#9 0x32b26636 in +[NSOperation observeValueForKeyPath:ofObject:change:context:] ()
#10 0x32b265aa in NSKVONotify ()
#11 0x32b13306 in -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] ()
#12 0x0007d6ec in -[ASIHTTPRequest markAsFinished] (self=0x5a7cc40, _cmd=0xa1710) at ASIHTTPRequest.m:2817
#13 0x00077e02 in -[ASIHTTPRequest failWithError:] (self=0x5a7cc40, _cmd=0x330cdfc4, theError=0x248130) at ASIHTTPRequest.m:1708
#14 0x000712dc in -[ASIHTTPRequest cancel] (self=0x5a7cc40, _cmd=0x322b4298) at ASIHTTPRequest.m:515
#15 0x0008884c in -[UIHTTPImageView setImageWithURL:placeholderImage:] (self=0x5a7c9d0, _cmd=0xa3f0c, url=0x5aa7760, placeholder=0x0) at UIHTTPImageView.m:21
#16 0x0006183c in -[MeetingView tiledScrollView:tileForRow:column:resolution:] (self=0x5a32560, _cmd=0x9bfac, tiledScrollView=0x5a74570, row=1, column=0, resolution=0) at MeetingView.m:1053
#17 0x0000475e in -[TiledScrollView layoutSubviews] (self=0x5a74570, _cmd=0x32299680) at TiledScrollView.m:181
#18 0x31515f32 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:] ()
#19 0x32c29ffa in -[NSObject performSelector:withObject:] ()
#20 0x30964798 in -[CALayer layoutSublayers] ()
#21 0x30964568 in CALayerLayoutIfNeeded ()
#22 0x30959b62 in CA::Context::commit_transaction ()
#23 0x3095997a in CA::Transaction::commit ()
#24 0x3097f164 in CA::Transaction::observer_callback ()
#25 0x32c702a0 in __CFRunLoopDoObservers ()
#26 0x32c23bb0 in CFRunLoopRunSpecific ()
#27 0x32c234e0 in CFRunLoopRunInMode ()
#28 0x30d620da in GSEventRunModal ()
#29 0x30d62186 in GSEventRun ()
#30 0x314d54c8 in -[UIApplication _run] ()
#31 0x314d39f2 in UIApplicationMain ()
#32 0x0000245c in main (argc=1, argv=0x2ffff5b4) at main.m:14
据我所知,这些行动是这样的:
据我所知,NSOperationQueue在被告知一个尚未启动的请求已完成后进入了一个糟糕的状态。回答我自己,作为我的结论和其他答案的综合 似乎ASIHTTPRequest(或者iOS)在取消请求时有点不稳定,特别是当有多个请求并且许多请求很快被取消和释放时 作为一个解决方案,我放弃了创建许多请求并在不再需要它们时取消它们的设计。我制作了一个包装器,将
ASIHTTPRequest
s存储在NSOperationQueue
中,该包装器还可以过滤URL,使相同的请求不会启动两次(如果出现单元格,则在图像完全加载之前消失,并再次显示)。我将所有请求结果(即图像)存储在缓存中
这可能会导致网络活动略微增加,但随着每个新请求的完成(即使图像可能不会显示)和缓存,其他一切都会变得更加清晰,因此不需要处理创建/取消等问题。。。因此不会再有崩溃。尝试在视图的dealloc中添加类似的内容:
[self.thumbnailRequest cancel];
self.thumbnailRequest.delegate = nil;
[self.thumbnailRequest setDidFinishSelector:NULL];
[self.thumbnailRequest setDidFailSelector:NULL];
self.thumbnailRequest = nil;
谢谢你的回答。我已经激活了Zombie,它指出问题是由一个为ASIHTTPRequest的一个释放实例调用的retain引起的。我不明白为什么会发生这种情况,因为在AsyncImageLoader中只完成了一次保留和释放,而ASIHTTPRequest应该保留足够的内容以正常工作。原因可能是,当我在loadImageFromURL中调用[self.request cancel]时,self.request已经被释放,但它应该设置为nil,因为主线程中调用了requestFinished/Failed方法。这很难说清楚,但我认为您可能需要做一些额外的重新分解。这就是我的意思。如果在当前请求仍挂起时滚动表视图,会发生什么情况?您传入了一个表视图单元格,我假设您将在图像下载完成后填充该图像,但如果用户现在已滚动,则您要显示的图像将是错误的图像。最好传入一个代理,以便在映像可用时通知它。然后,该代表可以确定是否仍应使用该图像填充当前单元格。换句话说,我的观点是,您需要重新考虑您的设计,这很可能有意或无意地解决此问题。嗯,我考虑了不同的概念,但我最终不得不取消一次图像下载,以避免启动几十个请求,这些请求将完全“免费”执行,并会减慢其他下载,甚至应用程序本身的速度。我会尝试改变一下设计,但是