【问题标题】:How to instantiate a pointer in objective-c如何在objective-c中实例化一个指针
【发布时间】:2016-02-16 14:27:49
【问题描述】:

假设我有一个指向ICScannerDevice 类型的指针,我已经为其分配了一些内存。现在,我想用ICDevice 类型的指针初始化它,它是ICScannerDevice 的父类。 我该怎么做?

以下是正确的方法吗?估计不行!

ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.

【问题讨论】:

标签: objective-c macos cocoa image-capture


【解决方案1】:

假设我有一个指向 ICScannerDevice 类型的指针,我已经为其分配了一些内存。

ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];

你在这里混淆了两件事。 变量是由声明创建的,一个声明也可以包含一个初始化表达式

当你声明一个变量空间被分配时,它可以包含变量的 typevalue - 该类型是否为int,在这种情况下该值将是一个整数,例如42ICScannerDevice *,在这种情况下,该值将是对分配的 ICScannerDevice 对象的引用。

所以声明:

ICScannerDevice* scannerDevice

提供存储ICScannerDevice * 类型值所需的所有空间。你给出的初始化表达式:

[[ICScannerDevice alloc] init];

在您的情况下是多余的(并且浪费),您不希望创建 ICScannerDevice 类型的对象并将对该对象的引用存储在 scannerDevice 中,因为您希望在变量中存储完全不同的引用:

现在,我想用 ICDevice 类型的指针初始化它,它是 ICScannerDevice 的父类。

scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.

这是错误的,因为您声明 device 持有对 ICDevice 对象的引用。由于ICDevice 类型是ICScannerDevice 的父类,因此对ICScannerDevice 的引用可以被视为对ICDevice 的引用——也称为“向上转型”。

然而,已知为ICDevice 类型对象的引用可能是也可能不是ICScannerDevice,它可能是ICPlotterDevice。所以你不能直接投射 - 也就是“downcast”和分配。

必须首先检查您是否确实引用了 ICScannerDevice。为此,您可以使用方法isKindOfObject: 检查引用对象的类型是否为ICScannerDevice 类型,并使用class 方法获得该类型:

if ( [device isKindOfObject:[ICScannerDevice class]] )
{
   // we have a reference to an ICScanner Device
   scannerDevice = (ICScannerDevice *)device;  // downcast and assign
    ...
}
else
{
   // device references something other than an ICScannerDevice object
   // handle this case
   ...
}

您还需要处理存储在 device 中的值是 nil 的情况 - 即它不引用任何内容。您可能只想将其与if 中的测试结合起来,并将其视为ICScannerDevice 参考:

if ( (device == nil) || [device isKindOfObject:[ICScannerDevice class]] )

或者您可能需要以其他方式处理它。

HTH

【讨论】:

    【解决方案2】:

    指针是保存对象所在内存地址的数字。

    指针是(16/32/64 位)并位于堆栈中。只是它的内容在堆上。

    因此,您不需要为指针分配任何空间。只为内容。因为 - 在你的情况下 - 你得到一个指向现有内容的指针。复制内存地址即可:

    ICScannerDevice* = (ICScannerDevice*)device; // device is a pointer to ICDevice. 
    

    注意:记住演员表不会改变内容!如果设备不是真正的 ICScannerDevice 而是其他设备,则可能稍后会崩溃。

    【讨论】:

      【解决方案3】:

      首先,如果您要立即将其他对象分配给它的引用,那么分配一个对象是没有意义的。

      其次,如果device 不是ICScannerDevice,则将其转换为一个错误可能会或可能不会导致问题,具体取决于您接下来如何处理。

      所以,答案是:不,这并不完全正确。

      (为了更好地回答你应该做什么,需要更多关于device来自哪里以及你想如何使用scannerDevice的上下文。)

      【讨论】:

      • 这不是真正的答案,更多的是评论/问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 2012-04-26
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多