Objective-C ++中的智能指针可以完全替代ARC吗?

问题描述 投票:0回答:1

我是可可框架的初学者,并有一个问题:

假设我在应用程序中未使用“裸” NS指针,那么,ARC对我来说多余吗? :-)

换句话说,以下实现是否涵盖了ARC的所有关注点? :-)

谢谢!

首先(“ alloc ..”,“ new ..”,“ copy ..”或“ mutableCopy ..”的结果累积:]

#pragma once

// In-Ref(NOP), Out-Ref(--)
template<typename T>
class NSChargePtr
{
  NSChargePtr(const NSChargePtr&) = delete;

protected:
  T* m_object{};

public:
  NSChargePtr(T* p = __nullptr)
    : m_object(p)
  {
  }
  virtual ~NSChargePtr()
  {
    [m_object release];
  }
  operator T*()
  {
    return m_object;
  }
  operator bool()
  {
    return __nullptr != m_object;
  }
  void operator=(T* p)
  {
    reset(p);
  }
  T* get()
  {
    return m_object;
  }
  virtual void reset(T* p = __nullptr)
  {
    [m_object release];
    m_object = p;
  }
}; 

...第二(本地保存,转移):

#pragma once
#include "NSChargePtr.h"

// In-Ref(++), Out-Ref(--)
template<typename T>
class NSPassPtr : public NSChargePtr<T>
{
public:
  NSPassPtr(T* p = __nullptr)
    : NSChargePtr<T>(p)
  {
    [NSChargePtr<T>::m_object retain];
  }
  NSPassPtr(const NSPassPtr& other)
    : NSChargePtr<T>(other.m_object)
  {
  }
  virtual void reset(T* p = __nullptr) override
  {
    NSChargePtr<T>::reset(p);
    [NSChargePtr<T>::m_object retain];
  }
  void operator=(T* p)
  {
    NSChargePtr<T>::operator=(p);
  }
};
c++ cocoa automatic-ref-counting objective-c++
1个回答
0
投票

简而言之:可以]执行此操作,但是它可能不会像“真实的” ARC一样轻松,并且尚不清楚这种方法是否比ARC有所改进。

一些立即出现在我身上的潜在问题:

  • 您在NSPassPtrNSChargePtr之间的区别已经是潜在混乱的主要根源。您需要确切地知道在哪种情况下使用哪种方法,具体取决于方法是返回自动释放值还是保留值。您也不能干净地将自动释放表达式的结果重新分配给使用保留表达式的结果初始化的变量。]​​>
    {
       NSChargePtr<MyClass> obj = [[MyClass alloc] init];
       // …
       obj = [foo bar];
       // …
    } // over-release of result of [foo bar];
    
    • 线程安全。在您的实施中,我看不到任何防御种族条件的证据。 ARC在多线程上下文中具有明确定义的行为。
  • 性能和编译器优化。编译器了解ARC,并可以在不需要证明的情况下取消保留和释放调用。此实现无法做到这一点。 ARC的objc_retain / objc_release可能比发送retain / release消息也快。
  • 隐式转换运算符重载(operator T*()operator bool,非explicit构造函数,例如NSChargePtr(T* p = __nullptr))往往是错误的来源。
  • 我应该指出,Objective-C ++与ARC兼容,并且在C ++对象构造/销毁的上下文中,ARC引用行为良好。因此,通常,如果您真的很难使某些代码与ARC一起使用,最好将其移至一个已禁用ARC的单独的代码文件中,而在项目的其余部分保持启用状态。

最后:

NSPassPtr(const NSPassPtr& other)
    : NSChargePtr<T>(other.m_object)
  {
  }

在我看来,它好像缺少retain

© www.soinside.com 2019 - 2024. All rights reserved.