关于isKindOfClass的问题

时间:2011-09-06 21:16:55

标签: objective-c

请查看此代码剪切

- (SoapRequest*)AddFlyData:(id)_target 
                    action:(SEL)_action 
                 sessionid:(int)sessionid 
                  datasets:(FlyNetArrayOfDataSet*)datasets
{
    if ([datasets isKindOfClass:[FlyNetArrayOfDataSet class]]) {
        NSLog(@"Yeah");
    } else {
        NSLog(@"Not Yeah");
    }
}

为什么,当我看到我的控制台时,我得到了

2011-09-06 23:08:00.917 soap-test[2133:207] Not Yeah

我是初学者而且我完全糊涂了..:■当我查看调试器时,变量类型是SoapArray(他是FlyNetArrayOfDataSet的父类)。

我使用SoapArray中的一个方法来启动我的'数据集'实例,这意味着该类自动定义为Soap而不是FlyNetArrayOfDataSet?!

谢谢

编辑:我犯了一个错误,它不是NSArray,但它继承自SoapArray

这是FlyNetArrayOfDataSet类的头文件

#import "Soap.h"

@interface FlyNetArrayOfDataSet : SoapArray
{
}

+ (NSMutableString*) serialize: (NSArray*) array;

@end

但这并没有解释为什么isKindOfClass返回false ..

EDIT2:好的,我的回答是我的问题..

我使用此方法初始化我的实例

FlyNetArrayOfDataSet * arr = [FlyNetArrayOfDataSet arrayWithObject:data];

这是超类SoapArray的静态方法,它创建一个SoapArray(Helper)的实例..但不是FlyNetArrayOfDataSet的实例(!)

看看它的实施:

+ (id)arrayWithObjects:(id)firstObj, ...{
    SoapArray* a = [SoapArray array];
    id eachObject;
    va_list argumentList;
    if (firstObj) {
        [a.items addObject: firstObj];
        va_start(argumentList, firstObj);
        while (eachObject = va_arg(argumentList, id)) {
            [a.items addObject: eachObject];
        }
        va_end(argumentList);
    }
    return a;
}

如果我像这样初始化我的实例

FlyNetArrayOfDataSet * arr = [[FlyNetArrayOfDataSet alloc] init];

它完美地工作,方法isKindOfClass返回true: - )

2 个答案:

答案 0 :(得分:4)

假设您有一个名为“FlyNetArrayOfDataSet”的类,它继承自(=是NSArray的子​​类)。

如果您实例化一个变量,如:

FlyNetArrayOfDataSet *arr = [[FlyNetArrayOfDataSet alloc] init];

如您所见,我正在使用NSArray方法初始化数组。但是,我的“arr”对象将是类型FlyNetArrayOfDataSet,而不是NSArray,因为我调用了FlyNetArrayOfDataSet类(请参阅[FlyNetArrayOfDataSet arrayWithObject....)。

NSLog(@"%d", [arr isKindOfClass:[FlyNetArrayOfDataSet class]]);
NSLog(@"%d", [arr isKindOfClass:[NSArray class]]);

两者都将返回“1”,这意味着“真”,因为arr是FlyNetArrayOfDataSet类的一个对象,它继承自NSArray。

修改 让我们看看我是否可以更好地解释它:

arr1 = [[FlyNetArrayOfDataSet alloc] init];
arr2 = [[NSArray alloc] init];

两个对象arr1和arr2都是使用相同的方法创建的,该方法在NSArray类中定义。但是,在第一种情况下,被调用的类是FlyNetArrayOfDataSet,在第二种情况下是NSArray。因此,arr1将是FlyNetArrayOfDataSet类的对象,而arr2将是NSArray类。

可以在此代码中看到差异:

NSLog(@"%d %d",
    [arr1 isKindOfClass:[FlyNetArrayOfDataSet class]]
    [arr1 isKindOfClass:[NSArray class]]
);
NSLog(@"%d %d",
    [arr2 isKindOfClass:[FlyNetArrayOfDataSet class]]
    [arr2 isKindOfClass:[NSArray class]]
);

此代码的输出为:

1 1 ( = true true)
0 1 ( = false true)

答案 1 :(得分:0)

因为FlyNetArrayOfDataSetSoapArraySoapArray FlyNetArrayOfDataSet

如果datasetsSoapArray的实例,您将在以下示例中看到“肥皂”:

- (SoapRequest*)addFlyData:(id)target
                    action:(SEL)action
                 sessionid:(int)sessionid
                  datasets:(FlyNetArrayOfDataSet*)datasets
{
    if ([datasets isKindOfClass:[FlyNetArrayOfDataSet class]]) {
        NSLog(@"Fly");
    }
    else if ([datasets isKindOfClass:[SoapArray class]]) {
        NSLog(@"Soap");
    }
    else {
        NSLog(@"???");
    }
}

SoapArray的实例也可能是FlyNetArrayOfDataSet。其他可能性是:

  • a SoapArray
  • FlyNetArrayOfDataSet以外的子类。