2013-06-07 2 views
0

Я не могу понять, почему я получаю эту ошибку и буду признателен за некоторые рекомендации.Переменная потеря ее выделения

Я устанавливаю переменную в методе viewDidLoad и NSLog возвращает ожидаемый результат от _myUser.email и _myUser.

Теперь, когда я вызываю переменную _myUser в любом методе (IBAction), он всегда вызывает сбой приложения. Я думаю, это потому, что он теряет выделение. В противном случае я не могу объяснить, почему это приведет к сбою приложения, если оно выполнено в другом месте. Но опять же ... Я делаю все, что знаю, что обеспечит доступность переменной &, установленной в приложении.

Я искал через приложение, и единственное место, где я установить _myUser находится в viewDidLoad, так что его не то, что я его с охраны нигде

редактировать: если я называю [self myOtherMethod] с самого конца ViewDidLoadNSLog будет работать, но не из любого другого метода.

edit2 он работает в другой части приложения, когда я сделать то же самое

User является NSManagedObject объектом Model является NSObject где я все мои модели запросов.

крах простого (lldb)

@property (strong, nonatomic) User* myUser; 

- (void)viewDidLoad 
{ 

    [super viewDidLoad]; 

    _model = [[model alloc]init]; 
    _myUser = [User alloc]; // I can do this or not do it and it gives me the same result 
    _myUser = [_model getCurrentUser]; 

    NSLog(@"First: %@",_myUser.email); 
} 
- (void) myOtherMethod { 
NSLog(@"Second: %@",_myUser.email); 
} 
+1

можете ли вы опубликовать информацию о том, что говорит консоль о сбое? – danh

+0

Вы используете ARC? – Chuck

+0

@CodaFi Я поставил Alloc как способ увидеть, было ли это недостатком, что вызывало его, –

ответ

-6
- (void)viewDidLoad 
{ 

    [super viewDidLoad]; 

    _model = [[model alloc]init]; 

    self._myUser = [[_model getCurrentUser] retain]; 

    NSLog(@"First: %@",self._myUser.email); 
} 
- (void) myOtherMethod { 
NSLog(@"Second: %@",self._myUser.email); 
} 

или

- (void)viewDidLoad 
    { 

     [super viewDidLoad]; 

     _model = [[model alloc]init]; 

     _myUser = [[_model getCurrentUser] retain]; // or copy if you owerdrive copyWithZone: metod 

     NSLog(@"First: %@",_myUser.email); 
    } 
    - (void) myOtherMethod { 
    NSLog(@"Second: %@",_myUser.email); 
    } 
+0

'self._myUser' ошибочно ...' self.myUser' - правильный путь ..... но в любом случае .. 'keep' в конце делал трюк ...' _myUser = [[_model getCurrentUser] сохранить]; ' –

+5

@JonathanThurft: Вы сказали, что используете ARC. Если вы можете скомпилировать этот код, вы не используете ARC. – Chuck

+1

Как сказал собеседник, 'self._myUser' ошибочен; свойство называется 'myUser', переменная экземпляра называется' _myUser', а 'self. ... 'обращается к свойству, а не (непосредственно) переменной экземпляра. Последний пример прав, но первый требует еще одного подчеркивания. Он также нуждается в еще одном сообщении 'keep': когда вы назначаете свойство' strong', метод setter свойства сохраняет объект. 'удерживайте его заранее, значит, он дважды удерживается, и поэтому будет просочиться. –

0

Порядочные правило, особенно для новых программистов Objective-C, чтобы всегда использовать свойство вместо экземпляра переменные и ссылаться только на _instanceVariable в getter и setter.

+0

Я думаю, что это неправильный способ думать об этом. Свойства являются и всегда были оболочками вокруг iVars (которые являются только смещениями памяти во внутренней структуре). Новичок должен знать это и понимать последствия назначения, вместо того, чтобы предполагать размахивание руками и магии с сеттерами. – CodaFi

3
_myUser = [User alloc]; // I can do this or not do it and it gives me the same result 
_myUser = [_model getCurrentUser]; 

Никогда не называть [SomeClass alloc] без немедленной отправки результата init (или их любого изменение) сообщения. Выделенный, но не инициализированный объект опасен; все может случиться, когда вы пытаетесь его использовать.

В этом коде это не имеет никакого значения, потому что вы немедленно замените объект User, который вы только что создали (но не инициализировали), с тем, который вы получили от [_model getCurrentUser].

Переменная и объект - это две разные вещи. Переменная является частью любого объекта, который вы объявили в этом свойстве (выглядит как какой-то контроллер вида), и представляет собой контейнер, содержащий ссылку на другой объект, который является объектом User, который вы получаете от модели. Переменная не «потеряет выделение»; пользовательский объект.

Это также объясняет, почему он не имеет смысла говорить что-то вроде:

_myUser = [[User alloc] init]; //This statement is unnecessary! 
_myUser = [_model getCurrentUser]; 

Первая строка создает новый объект пользователя, который не имеет ничего общего ни с чем, и сохраняет ссылку на это в вашей переменной _myUser, а вторая строка затем сразу заменяет эту ссылку на этот объект ссылкой с другим объектом-пользователем - «текущим пользователем», который вы получаете от модели. Одна переменная, два объекта.

крах простой (lldb)

«(lldb)» не своего рода аварии; это подсказка отладчика. Вам нужно посмотреть выше подсказки, чтобы узнать, что это за авария.

Он также может помочь просмотреть трассировку стека в навигаторе и точно увидеть, на какой строке вашего кода произошел сбой.

[Добавлено] Или введите bt в это приглашение, если у вас ничего нет в навигаторе. (По-видимому, LLDB ногами в Xcode без заметив это ошибка, которая начала появляться как в 10.8.4, в соответствии с парой других SO вопросов, которые я видел.)

retain в конце сделал трюк. ..

Тогда вы не используете ARC. Вы не можете отправлять сообщения retain в ARC, поэтому, если вы можете отправить сообщение retain, и ваша сборка будет успешной, это докажет, что вы не используете ARC.

Это, в свою очередь, указывает на то, в чем проблема: вы присвоили этому объекту User, который вы получили от getCurrentUser, к вашей переменной экземпляра, но поскольку вы не сохранили его или не присвоили ему свойство strong, оно вымерло из под вами, и с тех пор, как вы все еще держались за него, вы однажды потерпели крах, когда пытались использовать этот мертвый объект.

Я рекомендую включить ARC. Тогда вам не понадобится (или уметь) сохранить объект; просто присваивая ему переменную экземпляра, такую ​​как _myUser, выполнит задачу сохранения объекта.

Один из вариантов - это решение, которое вы выбрали (retain). другой должен был бы присвоить объекту свойство myUser (self.myUser), а не переменную экземпляра _myUser. Пока вы не используете ARC, просто присваивание переменной экземпляра не сохраняет объект; присвоение объекту strong делает, как и retain.

Смежные вопросы