Я протестировал некоторые isa swizzling с Swift и обнаружил, что он работает только тогда, когда NSObject является суперклассом (непосредственно или выше), или с использованием украшения '@objc'. В противном случае он будет следовать стилю статической и vtable-диспетчеризации, как C ++.
Нормально ли определять класс Swift без базового класса Cocoa / NSObject? Если это меня беспокоит, это означает отказ от большей части динамизма Objective-C, такой как перехват метода и самоанализ во время выполнения.
Динамическое поведение во время выполнения лежит в основе таких функций, как наблюдатели свойств, основные данные, аспектно-ориентированное программирование , обмен сообщениями высшего порядка , аналитические и журнальные структуры и т. Д.
Использование стиля вызова метода Objective-C добавляет к вызову метода около 20 операндов машинного кода, поэтому в определенных ситуациях ( много жестких вызовов методов с маленькими телами ) статическая отправка и отправка vtable в стиле C ++ могут работать лучше.
Но, учитывая общее правило 95-5 ( 95% прироста производительности достигается за счет настройки 5% кода ), не имеет ли смысла начинать с мощных динамических функций и укреплять там, где это необходимо?
источник
Ответы:
Классы Swift, являющиеся подклассами NSObject:
objc_msgSend()
для вызовов (большинства) их методовКлассы Swift, не являющиеся подклассами NSObject:
objc_msgSend()
для вызовов своих методов (по умолчанию)Создание подкласса NSObject в Swift дает вам гибкость выполнения Objective-C, но также и производительность Objective-C. Избегание NSObject может улучшить производительность, если вам не нужна гибкость Objective-C.
Редактировать:
В Xcode 6 beta 6 появляется динамический атрибут. Это позволяет нам указать Swift, что метод должен использовать динамическую отправку и, следовательно, будет поддерживать перехват.
источник
Я также обнаружил, что если базировать класс Swift на NSObject, я увидел некоторое неожиданное поведение во время выполнения, которое могло скрыть ошибки кодирования. Вот пример.
В этом примере, где мы не основываемся на NSObject, компилятор правильно определяет ошибку в testIncorrect_CompilerShouldSpot, сообщая «... 'MyClass' не может быть преобразован в 'MirrorDisposition'»
В этом примере, где мы основываемся на NSObject , компилятор не обнаруживает ошибку в testIncorrect_CompilerShouldSpot:
Думаю, мораль такова: только на основе NSObject, где вам действительно нужно!
источник
Согласно справочнику по языку, классы не обязаны создавать подкласс любого стандартного корневого класса, поэтому вы можете включать или опускать суперкласс по мере необходимости.
Обратите внимание, что исключение суперкласса из объявления класса не назначает неявный базовый суперкласс любого типа. Он определяет базовый класс, который фактически станет корнем для независимой иерархии классов.
Из справочника по языку:
Попытка сослаться
super
на класс без суперкласса (т.е. базового класса) приведет к ошибке времени компиляции.источник
Я считаю, что в подавляющем большинстве данных Swift не будет
objc
. Только те части, которые действительно должны взаимодействовать с инфраструктурой Objective C, будут явно отмечены как таковые.Я не знаю, до какой степени самонаблюдение во время выполнения будет добавлено к языку. Перехват метода, вероятно, станет возможным только в том случае, если метод явно разрешает это. Это мое предположение, но только разработчики языков в Apple действительно знают, куда они на самом деле движутся.
источник
educated guesses
через несколько лет. Но пока это просто большой вопросительный знак.Следующее скопировано из Swift-eBook от Apple и дает соответствующий ответ на ваш вопрос:
Определение базового класса
Любой класс, который не наследуется от другого класса, называется базовым классом.
Классы Swift не наследуются от универсального базового класса. Классы, которые вы определяете без указания суперкласса, автоматически становятся базовыми классами, которые вы можете использовать.
Ссылка
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251источник
Это нормально. Взгляните на цели дизайна Swift: цель состоит в том, чтобы избавиться от огромных классов проблем программирования. Смена методов, вероятно, не входит в число тех вещей, которые вы хотите делать со Swift.
источник