假设我有一个指向 ICScannerDevice 类型的指针,我已经为其分配了一些内存。
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
你在这里混淆了两件事。 变量是由声明创建的,一个声明也可以包含一个初始化表达式。
当你声明一个变量空间被分配时,它可以包含变量的 type 的 value - 该类型是否为int,在这种情况下该值将是一个整数,例如42 或 ICScannerDevice *,在这种情况下,该值将是对分配的 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