Использование типов перечислений как свойств в Objective C

Я - ветеран .NET-разработчика, делающий свой первый набег на программирование Objective C. У меня возникли трудности с свойством типа перечисления. В некотором контексте... У меня есть заголовок и перечисление класса:

typedef enum  {
    Open,
    Unavailable,
    Unknown
} LocationStatus;

@interface Location : NSObject {

    LocationStatus status;
}

@property (nonatomic) LocationStatus status;

@end

и реализация, которая выглядит так:

@implementation Location

@synthesize status;

@end

В какой-то момент кода я устанавливаю значение следующим образом:

location1.status = Open;

Затем отладчик оценивает это как правильное значение и разрешает правильное перечисление (обратите внимание также, что существуют другие свойства, которые здесь не показаны... они тоже правильно оценивают).

Позже в коде я попытаюсь прочитать это свойство следующим образом:

LocationStatus status = location.status;

В этот момент кода отладчик может правильно оценить все свойства моего класса, кроме Status, который показывает адрес памяти, но не фактическое значение. Когда выполнение достигает этой строки, я последовательно получаю ошибку EXC_BAD_ACCESS в консоли, и приложение вылетает.

Я уверен, что это отражает фундаментальное недоразумение с моей стороны о том, как использовать свойства и перечисления в Objective C (и, вероятно, C вообще). Если бы кто-нибудь мог пролить свет на это, я был бы очень благодарен.

Ответы

Ответ 1

Возможно, слишком поздно ответить на это, но я заметил одну вещь в вашем коде. Вы используете 2 разных переменных в вашем местоположении кода1 и местоположении (без 1).

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

Как вы отметили, вы не выделяете перечисление. Но это не перечисление, которое является проблемой. Синтаксис "точка" в objective-c является просто сокращением для отправки сообщения доступа.

Ваш код эквивалентен:

LocationStatus status = [location status];

Это отправляет синтезированное сообщение -(LocationStatus)status{} несуществующему объекту местоположения (если, конечно, location1 не является опечаткой в ​​вашем сообщении, но не в вашем коде, что делает мой комментарий неуместным). Так что просто измените location.status на location1.status, и вам должно быть хорошо идти (если, разумеется, location1 не будет отправлено сообщение).

Ответ 2

EXC_BAD_ACCESS почти всегда означает, что вы пытаетесь использовать ссылку на объект, который был освобожден (как правило, ошибка с высвобождением). Найдите эту ошибку здесь, чтобы найти много советов по ее отслеживанию.