我一直在阅读在Mac上学习目标C 这本书,我正在看这段示例代码:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSFileManager *manager;
manager = [NSFileManager defaultManager];
NSString *home;
home = [@"~" stringByExpandingTildeInPath];
NSDirectoryEnumerator *direnum;
direnum = [manager enumeratorAtPath: home];
NSMutableArray *files;
files = [NSMutableArray arrayWithCapacity: 42];
// “Slow” enumeration
NSString *filename;
while ( filename = [direnum nextObject] )
{
if ([[filename pathExtension] isEqualTo: @”jpg”])
{
[files addObject: filename];
} // end if
} // end while
NSEnumerator *filenum;
filenum = [files objectEnumerator];
while ( filename = [filenum nextObject] )
{
NSLog(@”%@”, filename);
}
[pool drain];
return 0;
} // main
对我来说最突出的是while ( filename = [filenum nextObject] )
我想,'这实际上是一个有条件的陈述?'我想对[filenum nextObject]
的调用是带有文件名的NSString,或 nil ,但是在我们评估时,我们如何执行filename =
?你能指出一些正确的文件,这些文件可以更清楚地解释这里有什么可能吗?
答案 0 :(得分:3)
这实际上是C的一个特性.while语句采用类似if语句的表达式,赋值是一个有效的表达式。在this C grammar file中,您可以看到以下内容有效
IF '(' expression ')' statement
以及
WHILE '(' expression ')' statement
只要表达式的结果为非零,条件就为真。 nil值为0,将导致条件失败。枚举器完成后,nextObject将返回nil,条件将失败。但是,建议在作为条件表达式进行赋值时,您应该用括号括起来表明您的意图。
while ( (filename = [direnum nextObject]) )
答案 1 :(得分:2)
这是一个条件语句,因为每个赋值都有一个值,该值是分配给左边var的右侧的值。
在这种情况下,最终值可以是有效的NSString
对象,也可以是nil。
只要nil
表示“无”,条件就会被解释为假,否则就是真的。
答案 2 :(得分:2)
while ( filename = [filenum nextObject] )
此声明很复杂,可执行多项操作。
[filenum nextObject]
方法被调用并返回NSString filename =
被分配了NSString的地址filename
的值被评估为while ( ... )
的条件
操作正如您所指出的,如果返回的值是nil
,那么filename等于nil
并且条件的计算结果为false,否则filename不为零,条件的计算结果为true。
许多程序员不喜欢这种语法。它很简洁,很难维护。编译器将生成警告,以标记开发人员实际打算比较这两个值时的常见语法错误,
while ( filename == [filenum nextObject] )
将原始陈述写为
会更清晰 while ( (filename = [filenum nextObject]) != nil )
此语句的行为与原始语句相同,但消除了赋值和条件操作的模糊性。
答案 3 :(得分:1)
你提出了一个很好的问题。考虑代码
while ( obj = [enumerator nextObject] ) {
printf( "%s\n", [[obj description] cString] );
}
while ( obj = [array objectEnumerator] )
工作的原因是因为objectEnumerator在最后一个对象上返回nil。因为在C nil中通常为0,所以这与false相同。 ( ( obj = [array objectEnumerator] ) != nil )
可能更合适
来源: Click This Link !
在您的情况下,((filename = [direnum nextObject]) )
是另一种方法,可以避免编译错误。
答案 4 :(得分:0)
表达式
(file = [filenum nextObject])
每次循环都会执行。在它被激活之后,它被评估为if语句的布尔条件
与
之类的普通陈述相同x = 13 * 4;
执行等于右边的所有内容,然后将其分配给变量x。