逻辑ANDing NSUInteger和字符串类型?

时间:2015-10-03 04:32:45

标签: objective-c logical-operators

我搜索过Stackoverflow和其他网站,但我似乎找不到这个答案。

在Apple Text Editor源代码中,他们至少有一个例程可以在两个非布尔变量之间进行一些明显奇怪的逻辑AND运算。将它们作为Bools进行投射可以完成,但没有多大意义。我正在学习Swift并且对Objective-C不那么熟悉,但对于我的生活,我无法弄清楚他们是如何努力实现所谓的“构建编码列表,排序,并且仅包括那些人类可读的名字。“

以下是代码:

/* Return a sorted list of all available string encodings.
*/
+ (NSArray *)allAvailableStringEncodings {
    static NSMutableArray *allEncodings = nil;
    if (!allEncodings) {    // Build list of encodings, sorted, and including only those with human readable names
        const CFStringEncoding *cfEncodings = CFStringGetListOfAvailableEncodings();
        CFStringEncoding *tmp;
        NSInteger cnt, num = 0;
        while (cfEncodings[num] != kCFStringEncodingInvalidId) num++;   // Count
        tmp = malloc(sizeof(CFStringEncoding) * num);
        memcpy(tmp, cfEncodings, sizeof(CFStringEncoding) * num);   // Copy the list
        qsort(tmp, num, sizeof(CFStringEncoding), encodingCompare); // Sort it
        allEncodings = [[NSMutableArray alloc] init];           // Now put it in an NSArray
        for (cnt = 0; cnt < num; cnt++) {
            NSStringEncoding nsEncoding = CFStringConvertEncodingToNSStringEncoding(tmp[cnt]);
            if (nsEncoding && [NSString localizedNameOfStringEncoding:nsEncoding]) [allEncodings addObject:[NSNumber numberWithUnsignedInteger:nsEncoding]];
        }
        free(tmp);
    }
    return allEncodings;
}

有问题的行包含“&amp;&amp;”。任何指导都将不胜感激。

1 个答案:

答案 0 :(得分:2)

Objective-C是C的严格超集,因此逻辑上的规则相同 运营商申请。与Swift相比,后者更为严格 类型中,C中的逻辑运算符采用任意标量操作数。 (布尔类型bool在早期版本的C中甚至不存在, 它是按照C99标准添加的。)

C标准规定(参见例如http://port70.net/~nsz/c/c11/n1570.pdf,这是C11标准的草案):

  

6.5.13逻辑AND运算符

     

约束

     

2每个操作数都应具有标量类型。

     

语义

     

3如果两个操作数都比较,&&运算符将产生1   不等于0;否则,它产生0.结果的类型为int

在你的情况下,在

if (nsEncoding && [NSString localizedNameOfStringEncoding:nsEncoding])

左操作数的类型为NSUInteger(可以是unsigned longunsigned int,取决于平台)和权利 操作数的类型为NSString *,它是指针类型。因此 上面的表达式相当于

if (nsEncoding != 0 && [NSString localizedNameOfStringEncoding:nsEncoding] != 0)

其中右操作数中的零是空指针常量 对于Objective-C指针,它通常写为NULLnil

if (nsEncoding != 0 && [NSString localizedNameOfStringEncoding:nsEncoding] != nil)

更多信息如何与Swift相关

Cocoa / Cocoa Touch返回对象指针的Objective-C方法 通常会返回nil来表示错误 (比较Handling Error Objects Returned From Methods 在“错误处理编程指南”中。所以

[NSString localizedNameOfStringEncoding:nsEncoding] != nil

意味着“无法确定编码的本地化名称”。 Swift等价物将是一个返回可选字符串的方法, 你可以用

检查成功
NSString.localizedNameOfStringEncoding(nsEncoding) != nil

然而,这不会编译,这就是为什么:如果您选择 - 单击Objective-C localizedNameOfStringEncoding方法 在Xcode中显示其声明,然后你会看到

+ (NSString * _Nonnull)localizedNameOfStringEncoding:(NSStringEncoding)encoding

此处_Nonnull表示该方法期望返回 nil。引入了这种可空性注释 改进Objective-C方法到Swift的映射,例如参见 在Swift博客中"Nullability and Objective-C"

由于此_Nonnull注释,该方法将导入Swift 如

public class func localizedNameOfStringEncoding(encoding: UInt) -> String

因此,可以在Objective-C中测试返回值,但不能 感觉因为该方法总是返回非nil值。 在Swift中,编译器假设返回值永远不会nil 并返回一个非可选的String

因此,将if语句转换为Swift只是

if nsEncoding != 0 {
    // ...
}