如何将NSArray的混合内容视为统一内容?

时间:2014-03-10 06:49:41

标签: objective-c nsarray

B类来自A类。 B类覆盖' - (NSString *)描述',也在A类中重写。 我创建了一个新的'NSArray'指向实例的指针,包括A类和B类。

是否有可能将一个循环中的所有循环视为A类实例,更确切地说 - 是否可以对所有这些实例使用A类' - (NSString *)描述?

目前,我使用检查它是否是B类实例,并在这种情况下调用生成A类实例的初始化程序。但似乎没必要,我不喜欢这个解决方案。

2 个答案:

答案 0 :(得分:1)

是的,你可以做到。

for (ClassA item in myMixedArray)
    NSLog("@%", item.description);

如果myMixedArray包含ClassA,ClassB的元素,则此选项有效。实际上(尽管不正确且非常混乱)它适用于任何类或对象指针,即使它们与A类或B类无关。唯一的问题是确保item实现description,否则它会失败。

在您的特定情况下,它是非常安全的,因为任何元素都会以某种方式成为ClassA对象(直接或继承)。

如果有一天你需要完全不相关的对象,你可以使用id作为迭代器类型。

for (id item in myMixedArray)
    [id someMethodThatAllObjectsImplement];
编辑(澄清被误解的问题):
在Objective-C中,没有简单的方法来强制对基类实现进行调用,与C ++不同,即使是类型转换指针也会无用。强制调用this question上解释的基类实现是一种棘手的方法。

答案 1 :(得分:0)

以下示例可能比Merlevede回答中提到的另一个解决方案中的解决方案更容易。

for ( id item in array )
{
    if ( [item isMemberOfClass:[ClassA class]] )
    {
        NSLog( @"%@", item );
    }
    else
    {
        struct objc_super parent = { item, [item superclass] };
        NSLog( @"%@", objc_msgSendSuper( &parent, @selector(description) ) );
    }
}

objc_msgSendSuper函数可用于调用任何返回id

的方法

编辑 - 忘了提及你需要

#import <objc/message.h>

编辑2 - 根据评论中OP的反馈,这是最终的解决方案

for ( id item in array )
{
    struct objc_super baseClass = { item, [ClassA class] };
    NSLog( @"%@", objc_msgSendSuper( &baseClass, @selector(description) ) );
}