Короче говоря: Вы можете сделать это, но это, вероятно, не будет таким же безболезненным, как "настоящий" AR C, и не ясно, что этот подход обеспечивает какое-либо улучшение более AR C. Почему вы даже хотите это сделать?
Некоторые потенциальные проблемы, которые сразу бросаются в глаза:
- Ваше различие между
NSPassPtr
и NSChargePtr
уже является основным источником потенциальная путаница. Вы должны точно знать, какой из них использовать в каком случае, в зависимости от того, возвращает ли метод автоматически выпущенное значение или оставшееся значение. Вы также не можете точно переназначить результат выражения автоматического высвобождения переменной, которая была инициализирована с результатом сохраняющего выражения.
{
NSChargePtr<MyClass> obj = [[MyClass alloc] init];
// …
obj = [foo bar];
// …
} // over-release of result of [foo bar];
- Безопасность потока. Я не вижу никаких доказательств защиты от условий гонки в вашей реализации. AR C имеет четко определенное поведение в контексте многопоточности.
- Производительность и оптимизация компилятора. Компилятор знает об AR C и может разрешить сохранять и освобождать вызовы, если он может доказать, что они не нужны. Это не может сделать это с этой реализацией. AR C
objc_retain
/ objc_release
, вероятно, быстрее, чем отправка retain
/ release
сообщений. - Неявные перегрузки оператора преобразования (
operator T*()
, operator bool
, не- explicit
конструкторы, такие как NSChargePtr(T* p = __nullptr)
), как правило, являются источником ошибок.
Следует отметить, что Objective-C ++ совместим с AR C и что AR C ссылки ведут себя хорошо в контексте конструирования / уничтожения объектов C ++. Поэтому, как правило, если вы действительно пытаетесь заставить какой-то фрагмент кода работать с AR C, лучше перенести его в отдельный файл кода с отключенным AR C, но оставить AR C включенным для остальных проекта.
Наконец:
NSPassPtr(const NSPassPtr& other)
: NSChargePtr<T>(other.m_object)
{
}
Мне кажется, что в нем отсутствует retain
?