Поскольку Metal Language также основан на C ++ 11, и C ++, кажется, идеально подходит, что является проверенным языком производительности, я собираюсь вообще обойти Objective-C / Swift. Я хотел бы остаться на C ++ арене. Есть ли возможность?
Технически да, но это было бы крайне уродливо и могло бы сломать некоторые другие части Objective-C.
Objective-C, как и C ++, начал свою жизнь как препроцессор. Одним из наследий этого является то, что каждый метод Objective-C также предоставляется как вызов функции C, который принимает экземпляр объекта и селектор метода в качестве первых двух аргументов соответственно, а затем другие объявленные аргументы в порядке слева направо.
И то и другое NSObject
и вызовы C, которые формируют среду выполнения Objective C, могут искать ток Функция C, которая будет вызываться для любого вызова метода.
Поэтому вы могли бы создать класс C ++, который бы захватывал все указатели на функции C (он мог даже делать это из среды выполнения C, делая его чистым кодом C ++, а не Objective-C ++), и сразу переходил к соответствующему коду.
Недостатки: Objective-C обычно использует динамическую диспетчеризацию (то есть метод, разрешенный для функции C при каждом вызове) и механизмы, подобные наблюдению значения ключа, работают только потому, что он использует динамическую диспетчеризацию. Если вы возьмете указатель на функцию C до того, как кто-то еще начнет наблюдать, ваши звонки будут выполняться для обновления свойства без уведомления наблюдателей. Таким образом, вы можете сломать некоторые модули.
Это предупреждение выдается, и предполагается, что вы можете просто построить свой класс моста C ++ как Objective-C ++ для более простого синтаксиса, например.
class MTLArray {
id m_instance;
static NSUInteger (* s_arrayLength)(id object, SEL selector);
};
MTLArray::MTLArray() {
// assuming you use the m_ pattern for instance variables
m_instance = [MTLArray new];
// assuming you use s_ for static variables; also pretending
// the mapping from method to C function will never change —
// KVO is the most prominent exception but otherwise you can
// be exceedingly confident, albeit you'll be relying on
// empirical behaviour, not the formal contract
if(!s_arrayLength) {
s_arrayLength = [MTLArray instanceMethodForSelector:@selector(arrayLength)];
}
}
NSUInteger MTLArray::getArrayLength() {
return s_arrayLength(m_instance, @selector(arrayLength));
}
… где я удобно отказался от результата +instanceMethodForSelector:
к соответствующему типу, потому что я уверен, что пойму неправильно. Я склонен выкуривать и вводить промежуточный typedef
в моем реальном коде, но вы можете быть более кратким.
Если вы хотите использовать API-интерфейсы Objective-C, но работать в основном на C ++, лучше всего подойдет Objective-C ++. Это просто Objective-C, но использующий C ++ вместо C в качестве основного языка.
Чтобы преобразовать класс Objective-C в Objective-C ++, просто измените суффикс исходного файла с «.m» на «.mm». (Вам также нужно обязательно включить правильную библиотеку времени выполнения C ++ во время ссылки.)
Как только вы это сделаете, вы можете использовать код C ++ внутри ваших методов Objective-C, включая типы шаблонов, такие как std :: vector, а также конструкции C ++ 11, такие как циклы на основе диапазона.
Нет. Металл выставлен только как Objective-C API. В лучшем случае вы можете обернуть его набором классов Objective-C ++, но это только добавит накладных расходов, вместо того, чтобы обходить Objective-C по вашему желанию.
Следующий проект с открытым исходным кодом предоставляет оболочку C ++ для Metal:
https://github.com/naleksiev/mtlpp