#iphone #release
#iPhone #выпуск
Вопрос:
В моем приложении есть корзина покупок. У меня также есть UIBarButton под названием «Пустая корзина». Я реализую функциональность для этой кнопки. Однако я столкнулся с некоторыми проблемами. Моя корзина — это одноэлементный объект данных. Что я хочу сделать, так это когда пользователь нажимает «Пустая корзина», все объекты и значения переменных в корзине должны быть освобождены и / или равны 0.
У меня есть метод «emptyCart», реализованный в моем ViewController, который, в свою очередь, вызывает метод «emptyCart» для CartSingleton. Моя проблема в том, что, как показано ниже, вызовы release для различных объектов не освобождают объекты, потому что, когда я печатаю содержимое корзины после запуска «empty cart», я все еще могу видеть все товары в корзине. Сообщение о выпуске не вступает в силу сразу? Как я могу мгновенно освободить все объекты в моей корзине в таком случае?
Код — «Пустая корзина» в Singleton:
-(void)emptyCart
{
if (self.selectedLocation != NULL)
{
[self.selectedLocation release];
self.locationSelected = false;
}
if (self.foodItemsArray != NULL)
{
for (int i = 0; i < [self.foodItemsArray count]; i )
{
FoodItem *temp = [self.foodItemsArray objectAtIndex:i];
if (temp.sidesArray != NULL)
{
[temp.sidesArray release];
}
}
[self.foodItemsArray release];
}
if (self.drinkItemsArray != NULL)
{
[self.drinkItemsArray release];
}
if (self.otherItemsArray != NULL)
{
[self.otherItemsArray release];
}
if (self.customerInfo != NULL)
{
[self.customerInfo release];
}
self.numFoodItems = 0;
//self.totalTaxPercent = 0;
self.foodItemsTotalCost = 0;
self.drinkItemsTotalCost = 0;
self.otherItemTotalCost = 0;
self.totalCostOfAllItems = 0;
self.totalTaxesAmount = 0;
self.totalChargesWithTaxes = 0;
self.gratuity = 0;
self.miscCharges = 0;
Комментарии:
1. Во-первых, вы должны сравнивать с
nil
вместоNULL
. Вы также можете отправлятьrelease
своим объектам, потому что Objective-C ничего не делает, если вы отправляете сообщения наnil
, он не прерывает работу и не генерирует исключение. Так что, даже еслиself.otherItemsArray
этоnil
так, просто вызовитеself.otherItemsArray = nil;
который сделает этоrelease
за вас (поскольку вы@synthesize
это сделали).2. Итак, вы хотите сказать, что мне не нужно делать это: [self.otherItemsArray release]; Вместо этого я должен сделать это: self.otherItemArray = nil; Я присвоил объект self.otherItemsArray следующим образом: self.otherItemsArray = [NSMutableArray alloc] initWithCapacity: 0]; Поскольку я использовал alloc, не означает ли это, что мне нужно использовать release ?
Ответ №1:
Немедленное освобождение освобождает — это означает, что это уменьшает количество сохранений, и если количество сохранений равно 0, то объект освобождается.
Ваша проблема в том, что вы сохраняете объекты — не устанавливаете переменные в nil после того, как закончите с ними.
Я также обеспокоен тем, что вы выпускаете слишком много раз
- Массивы освобождают свои элементы при их освобождении
-
сохраненные @properties освободят объект, для которого они установлены, если вы установите для них значение nil — вы должны очищать их следующим образом:
self.CustomerInfo = nil;
Итак, будьте осторожны. Похоже, что прямо сейчас вы обращаетесь к выпущенным объектам, которые в конечном итоге завершатся сбоем. Чрезмерное освобождение также вызовет проблемы.
Чтобы попытаться выяснить эти проблемы
- Используйте Build and Analyze и исправляйте ошибки, о которых он сообщает
-
Включите Zombies и посмотрите, получаете ли вы доступ к освобожденным объектам
http://www.loufranco.com/blog/files/debugging-memory-iphone.html
Комментарии:
1. Да, вы правы. После запуска empty cart мое приложение вылетает, когда я захожу в print cart с сообщением «КРОМЕ BAD ACCESS». Я собираюсь попробовать это так, как вы предлагаете. Спасибо за ваши предложения, я вскоре опубликую свои результаты.
2. Проверьте это loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html Я попытался подробно объяснить, что такое EXC_BAD_ACCESS, и дать советы по устранению неполадок.
Ответ №2:
release
не делает ничего большего, чем уменьшает количество сохранений для объекта. Среда выполнения, когда она замечает, что значение retain достигает нуля, затем вызывает dealloc
метод вашего объекта.
Следовательно, если у вас там все еще есть объекты, это означает, что другие объекты поместили функцию retain на объект (увеличивая его количество сохранений), что означает, что они останутся.
Комментарии:
1. Я понимаю. Спасибо за ваш ответ. Я проверю это.