Получить адрес свойства Objective-C (который является структурой C) - PullRequest
6 голосов
/ 09 июля 2009

У меня есть класс Objective-C, который содержит структуру в стиле C. Мне нужно вызвать функцию C, передав указатель на этот член объекта (свойство a.k.a.). На протяжении жизни я не могу понять, как получить адрес этой структуры Си. Используя традиционный оператор & для получения адреса, я получаю ошибку компилятора LValue.

typedef struct _myStruct
{
   int aNumber;
}MyStruct, *pMyStruct;

@interface MyClass : NSObject {
    MyStruct mystruct;
}
@property (readwrite) MyStruct myStruct;
@end

Следующий код приводит к ошибке компилятора:

MyClass* myClass = [[MyClass alloc] init];

MyStruct* p = &(myClass.myStruct);

Как получить указатель на myStruct член myClass объекта?

Ответы [ 4 ]

2 голосов
/ 10 июня 2015

Часто есть довольно веские причины для выполнения того, о чем говорится в первоначальном посте, учитывая, что приложения Objective-C часто должны работать с API C / C ++, которые используют указатели на структуры и подобные типы, но в приложении Cocoa вы будете часто хотят хранить такие данные в классах Objective-C для управления данными, сбора в массивы и словари и т. д.

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

- (const MyStruct*) getMyStructPtr
{
    return &mystruct;
}

Обратите внимание, что я использую объявленное свойство из OP, но не ссылаюсь на него как self.mystruct, что приведет к ошибке компилятора (потому что это вызывает синтезированный метод получения).

2 голосов
/ 09 июля 2009

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

- (void)getMyStructPointer:(MyStruct **)outStruct {
    *outstruct = &myStruct;
}

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

2 голосов
/ 09 июля 2009

Сам вопрос свидетельствует о непонимании хотя бы терминологии.

Свойство - это интерфейс, состоящий из двух (или одного для только для чтения) методов, обнародованных объектом, а именно методов getter и setter, в данном случае:

- (MyStruct) myStruct;
- (void) setMyStruct: (MyStruct) newMyStruct;

Нет смысла говорить о «захвате адреса имущества».

Вы можете взять адрес переменной экземпляра (ivar). В этом случае у вас есть ивар с именем mystruct, и вы можете взять его адрес с помощью &mystruct в методе MyClass. Поскольку он помечен @protected (по умолчанию), вы можете взять его адрес в подклассе, используя &self->mystruct. Если вы отметите его @public, то вы можете взять его адрес, используя &myobj->mystruct. Это ужасная идея, и вы должны действительно переосмыслить это, но вы могли бы сделать это.

Если вы просто хотите, чтобы адрес ивара использовался для кратковременных целей (например, если MyStruct был большим), вы могли бы сделать это, но это было бы очень необычно, и вам лучше было бы написать метод с явным именем как:

- (MyStruct*) getAddressForSettingMyStruct;

и если это только для чтения, еще лучше использовать const MyStruct *.

2 голосов
/ 09 июля 2009

MyStruct mystruct является приватным в MyClass, я полагаю, когда вы делаете myClass.myStruct, вы ссылаетесь только на сгенерированный метод доступа, а не на фактическую структуру.

Я не думаю, что вы можете получить доступ к переменной экземпляра (структура в данном случае) извне, потому что она закрыта.

...