我有一个解析器类,它是NSOperation的子类。它用于解析xml,并在完成解析时重新加载表视图。我有一个刷新UIBarButtonItem,用于调用解析器并再次从链接解析新的xml。
-(void)refresh {
[self.queue cancelAllOperations]; //cancel all the current operations
[self.queue release];
self.queue=nil;
self.arrayOfAllPhotos = nil; // The array to load table view
[self performSelectorOnMainThread:@selector(doItAgain) withObject:nil waitUntilDone:NO];
}
-(void)doItAgain {
[tableView reloadData];
NSURL *url = [NSURL URLWithString:@"some url"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *aconnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.myConnection = aconnection;
[aconnection release];
}
但是,作为按下刷新按钮,应用程序崩溃而没有消息。如何释放NSOperationQueue并再次开始新的解析以加载数据?
答案 0 :(得分:1)
您的内存管理已损坏。你违反了封装。您正在呼叫[self.queue release]
。这是通过释放self
拥有的东西而进入self
并打破它。
如果我要伸进你的腹部并释放你的肝脏,这可能都是为了国家的利益,但它可能对你不利。这个概念称为封装。这个概念被解释为here。
由于各种原因违反封装是不好的,这对self
来说很糟糕。
相反,只需致电self.queue = nil
,setQueue:
方法会在合适的时间为您释放queue
(就像arrayOfPhotos
一样)。
[self.queue cancelAllOperations];
self.queue = nil;
self.arrayOfAllPhotos = nil;
从这个问题的细节中退一步看来,您还可以花一些时间深入了解MVC范例。 WWDC 2010演讲(会议题目:iPhone OS的模型 - 视图 - 控制器)很棒,可以找到here(你必须登录)。
通常,将网络与表视图控制器混淆是一个坏主意。
祝你好运!答案 1 :(得分:1)
如果将队列定义为保留属性,则在此处:
[self.queue release];
self.queue=nil;
你正在过度释放队列:它首先是手动释放,然后是setter方法,因为队列仍然不是nil且不同于nil它将再次释放并设置为nil,第二次释放将导致崩溃。
这就足够了:
self.queue=nil;
答案 2 :(得分:1)
在调用cancelAllOperations
后,你应该小心,这是一个异步操作。确保所有操作被取消的最简单方法是执行以下操作:
[self.queue cancelAllOperations]
[self.queue waitUntilAllOperationsAreFinished];