发送到 iPhone 中已释放实例的消息
Posted
技术标签:
【中文标题】发送到 iPhone 中已释放实例的消息【英文标题】:Message sent to deallocated instance in iPhone 【发布时间】:2012-08-23 06:18:31 【问题描述】:我是 iPhone 新手,
我正在按照苹果here 的建议创建 NSURLConnection
但是当我关闭我的视图时我的应用程序崩溃了,我尝试了NSZombieEnabled
的概念,它显示了-[CALayer release]: message sent to deallocated instance 0x68b8f40
我在Webview
中显示一个网页,当用户点击webview 中的下载链接时,shouldStartLoadWithRequest
方法将在此方法中被调用,我正在创建NSURLConnection
。
这是我的代码 sn-p,
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
[receivedData setLength:0];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1
[receivedData appendData:data1];
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
DirPath=[self applicationDocumentsDirectory];
NSLog(@"DirPath=%@",DirPath);
[receivedData writeToFile:DirPath atomically:YES];
UIAlertView* Alert = [[UIAlertView alloc] initWithTitle:@"Download Complete !"
message:nil delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[Alert show];
[Alert release];
// release the connection, and the data object
[connection release];
[receivedData release];
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error1
[connection release];
[receivedData release];
// inform the user
NSLog(@"Connection failed! Error - %@ %@",
[error1 localizedDescription],
[[error1 userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
//CAPTURE USER LINK-CLICK.
Durl=[[url absoluteString]copy];
//Checking for Duplicate .FILE at downloaded path....
BOOL success =[[NSFileManager defaultManager] fileExistsAtPath:path];
lastPath=[[url lastPathComponent] copy];
if (success) //if duplicate file found...
UIAlertView* Alert = [[UIAlertView alloc] initWithTitle:@"This FILE is already present in Library."
message:@"Do you want to Downlaod again ?" delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"Yes",@"No",nil];
[Alert show];
[Alert release];
else //if duplicate file not found directly start download...
// Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:Durl]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection)
// Create the NSMutableData to hold the received data.
receivedData = [[NSMutableData data] retain];
else
NSLog(@"Inform the user that the connection failed.");
return YES;
我们将不胜感激。
【问题讨论】:
评论此行并检查[连接释放]; 已经试过了,但是不行。 你也评论了receivedData吗? 是的,我尝试了两种可能性,有评论和没有评论,但仍然崩溃。 NSLog(@" connection %p",connection); NSLog(@"receivedData %p",receivedData); NSLog(@"webView %p",webView);打印对象地址并检查是哪一个导致了崩溃。并且还在 connection 和 receivedData 对象上调用 retain。 【参考方案1】:确保在您的 dealloc 实现中将 delegate
重置为 nil
。另一个这样做的地方是viewWillDisappear:
。
您的应用程序崩溃/访问僵尸的原因是UIWebView
实例可能会尝试回调 viewController,即使它已经被释放。为了防止这种情况发生,您必须在 viewController 超出范围之前将 UIWebView
的 delegate
设置回 nil
。在 ios5 的 ARC 实现之前使用委托时,这是一个普遍的问题。 iOS5 最终提供了弱引用,这些实际上是 nil
本身,一旦它们的实例被释放。
示例 A:
- (void)dealloc
[...]
_webView.delegate = nil;
示例 B:
- (void)viewWillDisappaer:(BOOL)animated
[super viewWillDisappaer:animated];
_webView.delegate = nil;
编辑: 再次阅读您的问题后,我意识到僵尸是 UIView 或 UIControl,因为消息被发送到 CALayer。通过暂时删除所有与 webView 相关的代码,确保您的问题实际上与 web 视图有关。
【讨论】:
我不确定,但问题与webview无关,它与NSURLConnection
连接导致崩溃有关。【参考方案2】:
我认为这个NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
有问题
您正在创建一个带有委托自我的NSURLConnection
实例,当您关闭视图时,该视图上的所有内容都会得到deallocated
。但是当NSURLConnection
试图调用它的委托方法时会发生崩溃。
所以你需要在你的viewWillDisappear
中将NSURLConnection
的委托设置为nil,你需要在接口中创建NSURLConnection
的对象。
@interface yourClass
NSURLConnection *theConnection;
@end
在.m
theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
- (void)viewWillDisappaer:(BOOL)animated
[super viewWillDisappaer:animated];
theConnection.delegate = nil;
【讨论】:
以上是关于发送到 iPhone 中已释放实例的消息的主要内容,如果未能解决你的问题,请参考以下文章
如何查找匹配对象:-[CFArray _cfTypeID]:发送到已释放实例的消息