#iphone #uitableview #nsxmlparser #nsoperation
#iPhone #uitableview #nsxmlparser #nsoperation
Вопрос:
У меня есть класс синтаксического анализатора, который является подклассом 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 и снова запустить новый синтаксический анализ для загрузки данных?
Ответ №1:
Ваше управление памятью нарушено. И вы нарушаете инкапсуляцию. Вы вызываете [self.queue release]
. Это значит проникнуть в self
и сломать его, выпустив что-то self
принадлежащее.
Если бы я залез к вам в брюшную полость и освободил вашу печень, возможно, это было бы на благо страны, но, вероятно, было бы плохо для вас. Эта концепция известна как инкапсуляция. Концепция объясняется здесь.
Нарушение инкапсуляции плохо по множеству причин, и это плохо для self
здесь.
Вместо этого просто вызовите, self.queue = nil
и setQueue:
метод будет выпущен queue
для вас в нужное время (точно так же, как это делается для arrayOfPhotos
).
[self.queue cancelAllOperations];
self.queue = nil;
self.arrayOfAllPhotos = nil;
Делая шаг назад от подробностей этого вопроса, кажется, что вы также могли бы потратить некоторое время на более глубокое понимание парадигмы MVC. Доклад на WWDC 2010 (название сессии: Model-View-Controller для iPhone OS) об этом был фантастическим, и его можно найти здесь (вам нужно авторизоваться).
Как правило, это плохая идея объединять сеть с вашим контроллером табличного представления.
Удачи!
Ответ №2:
если очередь определена как сохраняемое свойство, то здесь:
[self.queue release];
self.queue=nil;
вы повторно освобождаете очередь: сначала она освобождается вручную, затем в методе setter, поскольку queue по-прежнему не равна нулю и отличается от nil, она будет снова освобождена и установлена на nil, а второй выпуск вызовет сбой.
этого будет достаточно:
self.queue=nil;
Ответ №3:
Вы должны быть осторожны после вызова cancelAllOperations
, это операция asynchoronos. Самый простой способ убедиться, что все операции были отменены, это сделать что-то вроде:
[self.queue cancelAllOperations]
[self.queue waitUntilAllOperationsAreFinished];