Использование переменной AppDelegate в качестве глобальной переменной - вопрос относительно выпуска / сохранения - PullRequest
3 голосов
/ 09 июля 2010

Я создал переменную под названием "myDBManager" в моем AppDelegate:

@interface myAppDelegate : NSObject <UIApplicationDelegate> {
   MyDBManager *myDBManager;
}
@property (nonatomic, retain)  MyDBManager *myDBManager;

@end

, который я использую в большинстве других классов в качестве глобальной переменной, содержащей все критически важные данные приложения. Он создается только один раз и умирает только в конце. Так, например, чтобы перейти к myDBManager в AnyOtherClass

@interface AnyOtherClass :  UITableViewController {
   MyDBManager *myDBManager;
   NSObject *otherVar;
}
@property (nonatomic,retain)   MyDBManager *myDBManager;
@property (nonatomic,retain)   NSObject *otherVar;
@end

//getting the data from "global" myDBManager and putting it into local var of AnyOtherClass
- (void)viewWillAppear:(BOOL)animated {
   //get the myDBManager global Object
   MyAppDelegate *mainDelegate = (MyAppDelegate *)[[UIApplication sharedApplication]delegate];
   myDBManager = mainDelegate.myDBManager;
   }


-  (void)dealloc {
       [otherVar release];
        //[dancesDBManager release]; DO NOT RELEASE THIS SINCE ITS USED AS A GLOBAL VARIABLE!
        [super dealloc];
        }

Вот мой вопрос: в то время как все другие локальные переменные AnyOtherClass, такие как «otherVar», должны быть освобождены в методе dealloc AnyOtherClass (всегда - это правильно?), Освобождение myDBManager в AnyOtherClass приводит к ошибкам в приложении ,

Поэтому я НИКОГДА не выпускаю локальную переменную myDBManager в любом классе моего приложения - все остальные локальные переменные всегда освобождаются - и она работает нормально. (Даже проверяя retainCount).

Прав ли я, что ВСЕ локальные переменные классов должны быть освобождены в результате освобождения этого класса, или это действительно нормально, чтобы вообще не освобождать эти переменные в случае использования конструкции глобальной переменной, как описано? (или любые другие случаи?)

Большое спасибо за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 09 июля 2010

В вашем сценарии myDBManager - это не глобальная или локальная переменная, это автоматически сохраняемое свойство (помеченное retain).Согласно Язык программирования Objective-C: объявленные свойства , nonatomic,retain свойства должны быть явно освобождены в dealloc.Однако, если ваше свойство синтезировано, у вас нет доступа к переменной-члену поддержки, поэтому вы не можете вызвать release для него;Вы должны использовать свойство setter, чтобы установить его на nil, что отправит release к предыдущему значению.Вы случайно не устанавливаете свойство myDBManager в AnyOtherClass и myAppDelegate в nil?

Обновление : @ Дон ответ на самом деле правильный.Вы не вызываете установщик свойств (self.myDBManager), поэтому автоматическое сохранение не срабатывает. Я оставлю свой ответ, чтобы люди могли учиться на моей ошибке.: -)

2 голосов
/ 09 июля 2010

Вы не сохранили его, когда ссылаетесь на него в AnyOtherClass, поэтому выпуск на этот момент не ваш. Вы устанавливаете ivar напрямую, поэтому сохранение в собственности не вступает в игру. Если вы позвонили

self.myDBManager = mainDelegate.myDBManager;

вы бы сохранили его, и вам пришлось бы освободить его, когда вы освободите класс.

Но, если это глобальная переменная, почему бы не использовать ее таким образом в AnyOtherClass? Почему бы не позвонить mainDelegate.myDBManager, когда вам нужен менеджер БД?

...