Объект C ++ как свойство Objective-C ++ - PullRequest
0 голосов
/ 28 августа 2018

Я хочу объявить свойство C ++ внутри моего класса Objective-C.

Какие атрибуты мне следует установить? Кажется, что strong или retain приведет к ошибке, говорящей, что это не объект.

Как мне правильно управлять памятью?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Вы правы, свойство не может быть weak, strong или retained; для этого это должен быть указатель на объект Objective-C. Если вы не используете никаких атрибутов в свойстве C ++, по умолчанию оно будет равно unsafe_unretained,assign,atomic.

Несколько других вещей, которые следует учитывать, если предположить, что объект Objective-C (++) управляет временем жизни свойства C ++:

  • Поскольку вы не можете многое сделать с объектом C ++ в Objective-C,
    свойство в основном полезно в коде Objective-C ++, где вы можете смешивать
    Objective-C и C ++.
  • Поскольку вам приходится управлять памятью объекта самостоятельно, вы нужен пользовательский установщик.
  • Поскольку для свойства по умолчанию установлено значение atomic, необходимо использовать синхронизация в сеттере и тоже нужен собственный геттер. Вы может объявить это nonatomic, в этом случае вам не нужно синхронизировать и не требует специального геттера.
  • Вы можете реализовать dealloc, чтобы обеспечить освобождение объекта C ++ при объект Objective-C ++ исчезает.

Вот несколько полезных документов от Apple: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html.

А вот краткий пример. Допустим, класс C ++, который вы используете для свойства, называется MyCPP. В заголовке вы могли бы иметь:

@interface ClassOCPP : NSObject

// This property can only be used in Objective-C++ code
#ifdef __cplusplus
@property /*(unsafe_unretained,assign,atomic)*/ MyCPP * myCPP;
#endif

// Other stuff may be usable in regular Objective-C code.

@end

Реализация может быть следующей (в файле .mm; помните, это Objective-C ++):

@implementation ClassOCPP
{
    MyCPP * _myCPP;
}
-(id)init {
    self = [super init];
    _myCPP = NULL;
    return self;
}

-(void)setMyCPP:(MyCPP*)newVal {
    @synchronized(self) {
        delete _myCPP;  // it's OK to delete a NULL pointer
        _myCPP = newVal;
    }
}

-(MyCPP*)myCPP {
    return _myCPP;
}

-(void)dealloc {
    puts("De-allocating ClassOCPP.");
    delete _myCPP;
}

@end
0 голосов
/ 29 августа 2018

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

...