Как правильно объявить закрытую переменную-член для класса Objective-C? - PullRequest
0 голосов
/ 06 февраля 2011

У меня возникли проблемы при назначении переменной для работы в следующем инициализаторе:

- (id)initWithBaseURL:(NSString *)url  {
  self = [super initWithNibName:@"MyNibName" bundle:nil];
  if (self) {
    baseURL = [url copy];
  }

  return self;
}

Я проверил, что параметр url действителен с соответствующим содержимым (созданным как NSMutableString, созданным через NSXMLParser, затем проверенным в методе initWithBaseURL в отладчике), но после присвоения результата операции копирования baseURL, baseURL переменная находится вне области видимости и остается недействительной. Любые попытки доступа к переменной baseURL в других методах класса приводят к ошибке EXC_BAD_ACCESS.

Я объявил baseURL в файле .h следующим образом, без операций @property или @synthesize, поскольку я пытаюсь использовать его в качестве закрытой переменной-члена:

@interface SignInViewController : UIViewController {
  // other variables

  @private
  NSString *baseURL;
}

// Other @property delcarations, IBAction method declartions, and method declarations

@end

Я также пытался использовать описанную технику здесь , но это только вызывает ошибку EXC_BAD_ACCESS в инициализаторе.

Что я делаю, что может вызвать ошибки EXC_BAD_ACCESS, и как я могу это исправить?

Ответы [ 2 ]

4 голосов
/ 06 февраля 2011

Вот пара наблюдений, которые могут иметь или не иметь отношения.

  • Код, который вы разместили, абсолютно нормален с точки зрения Obj-C.
  • Вместо [super init] вы должны действительно вызвать инициализатор, назначенный UIViewController, initWithNibName:bundle:.
  • Вы назвали метод initWithBaseURL:, но он принимает NSString в качестве аргумента.Хотя это соответствует объявлению в @interface, убедитесь, что baseURL не является объектом NSURL где-то еще в вашем коде.
  • Что происходит, когда вы удаляете @private?Я подозреваю, что ничего не меняется в отношении исключений, которые вы видите.

Убедитесь, что вы этого не делаете:

NSString *myURL = [NSString stringWithFormat:...]; // myURL is autoreleased
SignInViewController *controller = [[SignInViewController alloc] initWithBaseURL: myURL]; // retains myURL because it's immutable
[myURL release]; // does not crash because myURL has been *retained*
// baseURL is left with 0 retain count

Вы можете проверить, что отправка copy в NSMutableStringдействительно производит другой объект, в то время как отправка copy в неизменяемую строку NSString эквивалентна retain только потому, что тратить память на точные копии неизменяемых объектов неэффективно.Если baseURL действительно была копией myURL, то сбой произошел бы при сливе пула автоматического выпуска.

Другими словами, ошибка может быть в одном месте и проявляться только в другом.,Приведенный выше пример не слишком надуманный.

3 голосов
/ 06 февраля 2011

вы заявили это правильно. Кроме того, опубликованная вами программа верна.

корр:

как поймал Costique: вам нужно позвонить через один из назначенных инициализаторов суперкласса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...