Возможно ли, что вы получаете EXC_BAD_ACCESS
?Возможно ли, что приложение аварийно завершает работу, потому что tabsView
освобождается при отправке на него isDescendantOfView:
.Если вы запускаете с включенными точками останова, он должен сообщить вам причину сбоя.Если это проблема EXC_BAD_ACCESS
, попробуйте NSZombie
.
. Чтобы активировать NSZombie, сделайте следующее:
- Получите информацию об исполняемом файле.
- Goк вкладке аргументов.
- В разделе «Переменные для установки в среде:» добавьте:
Имя: NSZombieEnabled Значение: ДА
Затем запуститеприложение, как обычно, и когда оно выходит из строя, оно должно сообщить вам, какой освобожденный объект получил какое сообщение.
РЕДАКТИРОВАТЬ: Только что увидел ваше редактирование.Я думаю, что прибил это.Вы автоматически высвобождаете представления при их создании, поэтому, когда они удаляются из своих суперпредставлений, они больше не сохраняются и, таким образом, освобождаются.В вашем приложении происходит сбой, потому что вы пытаетесь запустить методы для освобожденных представлений.
РЕДАКТИРОВАТЬ 2: Думаю, я должен сказать вам, что есть лучшее решение, чем опубликованное Praveen S.
Измените код следующим образом:
[tabsClippedView release];
tabsClippedView = [[UIView alloc] initWithFrame:tabsClippedFrame];
и
[tabsView release];
tabsView = [[UIView alloc] initWithFrame:tabsFrame];
Приведенный выше код действует так же, как код, опубликованный Praveen S, но безautorelease.Авто-релиз дороже, чем обычный выпуск, и его следует использовать только при необходимости, и в этом случае это не так.
Вместо того, чтобы выпускать перед выделением нового представления, вы, вероятно, захотите освободить представление, когда вы 'с этим:
[tabsView removeFromSuperview];
[tabsView release];
tabsView = nil;
или просто
[tabsView removeFromSuperview];
self.tabsView = nil;
, а затем вместо:
if ([tabsView isDescendantOfView:tabsClippedView]) ...
вы можете использовать:
if (tabsView) ...
Как вы могли заметить, вам действительно не нужно сохранять вид.Вы также можете сделать следующее:
tabsView = [[UIView alloc] initWithFrame:tabsFrame];
[tabsClippedView addSubview:tabsView]; // This retains tabsView
[tabsView release];
, а затем удалить вид, который будете использовать:
[tabsView removeFromSuperview]; // This will release the tabsView
tabsView = nil;
Также не забудьте установить nil в viewDidUnload
.
РЕДАКТИРОВАТЬ 3: Почему self сделал такую разницу:
Вам нужно понять, как работают свойства и счетчик ссылок.Есть книги и такие, о которых вы могли бы прочитать.Я уверен, что Google также может предоставить вам несколько хороших ссылок.
Разница между
self.tabsView = [[UIView alloc] initWithFrame:frame];
и
tabsView = [[UIView alloc] initWithFrame:frame];
в том, что self.tabsView
осуществляет доступустановщик свойств, в то время как tabsView
непосредственно обращается к переменной экземпляра.
Реализация неатомического свойства сохранения выглядит примерно так:
- (void)setTabsView:(UIView *)view
{
if (view != tabsView) {
[tabsView release];
tabsView = [view retain];
}
}
Таким образом, свойство заботится оуправление памятью для вас.В моем решении я сам позабочусь об управлении памятью, и поэтому мне не нужно это свойство для меня, поэтому я им не пользуюсь.
Надеюсь, это объясняет, почему self сделал такую разницу.