Xcode отказывается от компиляции при попытке получить свойство из пользовательского объекта из массива - PullRequest
1 голос
/ 12 июня 2011

В последнее время я много сталкиваюсь с этой проблемой.У меня есть NSMutableArray с именем tests, который заполнен экземплярами моего пользовательского класса Test.Я пытаюсь получить доступ к свойству следующим способом:

return [tests objectAtIndex:row].name;

Однако LLVM всегда выдает ошибку и отказывается от компиляции:

error: Semantic Issue: No member named 'name' in 'struct objc_object'

Как мне сообщить компилятору, что яВы будете получать доступ к объекту Test и позволить мне скомпилировать проклятую вещь?

Ответы [ 4 ]

5 голосов
/ 12 июня 2011

Чтобы использовать точечную запись для свойств, компилятору нужно знать тип объекта.

Вы можете отправить сообщение:

return [[test objectAtIndex:row] name];

Или вы можете привести приведенное значениеobjectAtIndex::

return ((Test*)[tests objectAtIndex:row]).name;

Вы можете удивиться, почему.Компилятору необходимо знать тип объекта, потому что свойство может назначать любой метод для получения или установки, а не просто пару по умолчанию name и setName:, например, это обычно для BOOL свойств:

@property(getter=isEditable) BOOL editable;

Таким образом, компилятору необходимо знать, какое это свойство, чтобы сгенерировать правильные вызовы доступа.

2 голосов
/ 12 июня 2011

Поскольку objectAtIndex: возвращает id, то есть универсальный указатель, компилятор не может знать, какое имя метода заменить для доступа к вашему свойству .name.

Вы должны полностью указатькомпилятору, что вы хотите сделать в этом случае.Либо укажите точное имя метода:

[[tests objectAtIndex:row] name];

, либо укажите фактический тип объекта:

((Test *)[tests objectAtIndex:row]).name;

Когда вы пишете foo.bar, компилятор должен искать в fooи найдите имена методов, связанные со свойством bar.Обычно это bar / setBar:, но они могут быть чем угодно; * из-за этой неоднозначности компилятору необходимо знать фактический класс foo.Учитывая только общий указатель, он не может найти эту информацию.

Предупреждение указывает, что компилятор также проверил, является ли объект в левой части . структурой с полем с именемname.Нет такого поля, поэтому компилятор не знает, что вы от него хотите.


* Например, @property(retain, setter=putThisValueIntoBar, getter=hamAndEggs) Bar * bar;

1 голос
/ 12 июня 2011

Или вы можете кастовать это так:

return ((Test*)[tests objectAtIndex:row]).name;
1 голос
/ 12 июня 2011

Добавление явного приведения должно сработать.

Test *test = [tests objectAtIndex:row];
test.name

Или отправьте сообщение вместо вызова метода.

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