如果我将子类实例分配给类型为父类的属性,是否保留子类属性



我有一个加载数组的提要:

Status对象

PhotoStatus对象 - Status 的子类

当用户单击源中的状态时,它会将他们带到具有以下属性的ViewCommentsViewController必须设置该属性才能使视图控制器正常工作:

@property (nonatomic,strong) Status *status;

如果我通过/分配:

  ViewCommentsViewController.status=photoStatus;  

我还能以某种方式可靠地保留photoStatus的子类属性吗?也许通过在我的视图控制器中执行类似photoStatus *revertedPhotoStatus=status;的操作,或者执行 im 尝试执行的操作的正确方法是什么?我不想有多个视图控制器类,也不想走在我的ViewCommentsViewController中同时拥有photoStatusstatus属性的草率路线,那么我如何可靠地允许加载多种类型的内容,这些内容都是Status的子类?

我能否可靠地保留照片状态的子类属性

是的,这会自动发生。它被称为多态性:一个事物就是它本来的样子,而不是你碰巧把它键入的东西。因此,如果将实际的 PhotoStatus 对象分配给类型为状态的变量,它仍然是底层的 PhotoStatus。这一机制绝对至关重要;没有它,子类实例将不是很有用!

但是请注意,为了将状态类型的对象视为 PhotoStatus 对象,如果这是它的真实情况,则需要将其转换为 PhotoStatus 对象。如果您这样做并且这恰好不是 PhotoStatus 对象,那么当 PhotoStatus 消息发送到实际上不是 PhotoStatus 的对象时,您可能会在稍后崩溃。

在所有世界中,你不需要测试某物是什么样的类。 相反,接收对象的类将声明一个指向实现所有必要方法的基类的指针。

实现会有所不同,但在这种情况下,ViewCommentsViewController可以对任何类型的Status进行一致的调用,并知道这些方法存在。

另一种构建事物以确保这一点的方法是使用协议。 这将使您的声明类似于@property (nonatomic,strong) id<StatusProvider> status;.

我打字isKindOfClass太频繁了,无法将自己表现为任何类型的纯粹主义者,但是在可能的情况下使用干净的方法是很好的。

如果您打算使用在 Status 类中定义但不在 PhotoStatus 中定义的方法,则需要检查返回对象的类。为此,您通常需要执行以下操作:

Status *status = viewCommentsViewController.status;
if ([[status class] isSubclassOfClass: [PhotoStatus class]])
{
    PhotoStatus *photoStatus = (PhotoStatus *) status;
    // Handle photoStatus.
}
else
{
    // Handle the other case.
}

如果要在呼叫站点保存几行,可以添加如下访问器:

@implementation Status
- (PhotoStatus *) asPhotoStatus
{
    return nil;
}
@end
@implementation PhotoStatus
- (PhotoStatus *) asPhotoStatus
{
    return self;
}
@end

然后只需致电

[[viewCommentsViewController.status asPhotoStatus] doSomething];

编辑:从Xcode 4.2开始,向nil发送消息应始终返回零值或使返回的结构填充零。(不幸的是,我找不到规范,但这篇博文包含一个摘要。

最新更新