Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone ASIHTTPRESS dealloc和EXC\u BAD\u访问问题_Iphone_Objective C_Exc Bad Access_Asihttprequest_Dealloc - Fatal编程技术网

Iphone ASIHTTPRESS dealloc和EXC\u BAD\u访问问题

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

我正在使用一组ASIHTTPRequest包装器(AsyncImageLoader)在UITableView中下载单元格的图像

我在处理ASIHTTPRequests时遇到问题。如果我释放它们,如果我在它们试图加载图像时不断上下滚动,我最终会有一个EXC_BAD_访问权限

这是我的包装纸的样子
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
据我所知,这些行动是这样的:

  • 请求被创建并启动,因此被添加到队列中
  • 请求在开始运行之前被取消
  • 请求已成功取消、从队列中删除并解除分配
  • 另一个请求完成,并且在解除分配的请求上保留比调用更多的队列
  • 作为一个实验,我额外尝试了一次保留请求——这会停止崩溃,但队列会停止运行

    有可能ASIHTTPRequest仍然以某种方式错误地处理了取消请求,但我发现很难看到如何处理

    更新

    这应该可以解决这个问题:


    据我所知,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方法。这很难说清楚,但我认为您可能需要做一些额外的重新分解。这就是我的意思。如果在当前请求仍挂起时滚动表视图,会发生什么情况?您传入了一个表视图单元格,我假设您将在图像下载完成后填充该图像,但如果用户现在已滚动,则您要显示的图像将是错误的图像。最好传入一个代理,以便在映像可用时通知它。然后,该代表可以确定是否仍应使用该图像填充当前单元格。换句话说,我的观点是,您需要重新考虑您的设计,这很可能有意或无意地解决此问题。嗯,我考虑了不同的概念,但我最终不得不取消一次图像下载,以避免启动几十个请求,这些请求将完全“免费”执行,并会减慢其他下载,甚至应用程序本身的速度。我会尝试改变一下设计,但是