如何检查对象是否是Cocoa中的Foundation对象?

时间:2011-12-13 14:59:04

标签: objective-c cocoa core-foundation

有没有办法找出Cocoa中的任意对象是否是Foundation对象?我在谈论NSString,NSArray,NSDictionary等。

让我详细说明......

基础对象(AFAIK)具有一些共享特征:它们都实现了NSCoding协议,它们都可以进入PList等。

因此,例如,如果我想将对象图存档到磁盘,那么确保我添加到对象图中的任何对象都是基础对象或我已实现NSCoding的自定义对象以及它是有用的看起来很傻:

if ([myObject isKindOfClass:[NSString class]] || 
    [myObject isKindOfClass:[NSNumber class]] || 
    [myObject isKindOfClass:[NSArray class]] || 
    [myObject isKindOfClass:[NSDictionary class]] || 
    [myObject isKindOfClass:[NSSet class]] || 
    ...) {
    //add myObject to object graph
}

这是一个简单但可能无用的例子,我遇到的问题是我编写的一些代码,它使用带有%@说明符的格式字符串将字典转换为url params字符串,但我不知道不要让任意对象进入那里,因为我不想在我的url params中使用内存地址:

//convert dictionary into url params string
[postDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    if ([key isKindOfClass:[NSString class]] && ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])) {
        [tempPost appendFormat:@"%@=%@&", key, obj];
    }
    else {
        *stop = TRUE;
    }
}];
NSString *post;
if ([tempPost length] > 0) {
    post = [tempPost substringToIndex:[tempPost length] - 1];
}

4 个答案:

答案 0 :(得分:1)

我不确定你的意思。你在问哪些课程是toll-free bridged吗?

答案 1 :(得分:1)

根据您要做的事情 - 如果您正在编写某种诊断并且只是想要排除核心类,您可以尝试获取类的名称并查看前几个字母。

if ([someObj.class.description hasPrefix:@"NS"]) {
  NSLog(@"Well, it's an NSSomething object...");
}

答案 2 :(得分:1)

你总是可以要求它上课 但是你不应该根据这些代码做出一些逻辑决定a path to the dark side, that is... 但严重的是,Apple将NSString暴露为cluster class,这意味着它有很多不同的类别,其中任何一个都可以归还给你,并且没有保证在未来它们将是相同的,命名可能会改变,等等 即使我怀疑像NSString这样的旧类会让它的底层结构发生变化,我也不会将这种可能性排除在外并对其进行赌注。

答案 3 :(得分:1)

  

基础对象(AFAIK)具有一些共享特征:它们都实现了NSCoding协议,它们都可以进入PList等。

这些都不是真的。只有一些类符合NSCoding,并非所有类都在Foundation中,并且只有少数几个类是属性列表类。

你当然可以使用Apple的一个归档器从一个对象生成一个plist,但是该对象必须符合NSCoding - 见上文。

  

因此,例如,如果我想将对象图存档到磁盘,那么确保我添加到对象图中的任何对象都是基础对象或我已实现NSCoding的自定义对象将是有用的。 / p>

您可以使用NSCoding测试对象是否符合[someObject conformsToProtocol:@protocol(NSCoding)]

如果您需要测试对象是否是属性列表对象,则必须通过测试类成员身份来完成此操作,就像您在问题中所示。这样的测试将包括Core Foundation属性列表对象,这是正确的:CF属性列表对象在属性列表中与它们的Foundation对应物一样有效,主要是因为CF和Cocoa属性列表对象是可互换的(由于免费电话)。

有效的属性列表类的完整列表包含Property List Programming GuideProperty List Programming Topics for Core Foundation。当然,类名是不同的(CFString与NSString),但由于免费桥接,它们是可以互换的。

对于所有意图和目的,NSString 是CFString,反之亦然,并且对于每一对其他免费桥接类都是相同的。 想到“NSStrings vs. CFStrings”没有帮助;相反,请记住它们是相同的东西,并将它们视为这样。

  

我遇到的问题是我编写的一些代码,它使用带有%@说明符的格式字符串将字典转换为url params字符串,但我不想让任意对象进入那里因为我不想在我的网址中使用内存地址...

这是类成员测试的有效案例。

//convert dictionary into url params string
    if ([key isKindOfClass:[NSString class]] && ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]])) {
        [tempPost appendFormat:@"%@=%@&", key, obj];
    }

您会在网址末尾找到&

我之前描述过a specification for an object that formats URL query strings。您可以在该对象的实现中包含类成员测试。