Использование перечислимых типов в качестве свойств в Objective C - PullRequest
13 голосов
/ 27 октября 2009

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

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 в целом). Если бы кто-нибудь мог пролить свет на это, я был бы очень признателен.

Ответы [ 2 ]

7 голосов
/ 20 февраля 2010

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

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

Как вы заметили, вы не выделяете перечисление. Но проблема не в перечислении. Синтаксис «точка» в target-c - это всего лишь короткий путь для отправки сообщения доступа.

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

LocationStatus status = [location status];

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

5 голосов
/ 27 октября 2009

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

...