我搜索过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;”。任何指导都将不胜感激。
答案 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 long
或unsigned int
,取决于平台)和权利
操作数的类型为NSString *
,它是指针类型。因此
上面的表达式相当于
if (nsEncoding != 0 && [NSString localizedNameOfStringEncoding:nsEncoding] != 0)
其中右操作数中的零是空指针常量
对于Objective-C指针,它通常写为NULL
或nil
:
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 {
// ...
}