我一直在研究苹果低端文件部分中的使用目录枚举器示例。
下面是一个代码片段:
for (NSURL *url in enumerator) {
// Error-checking is omitted for clarity.
NSNumber *isDirectory = nil;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];
if ([isDirectory boolValue]) {
NSString *localizedName = nil;
[url getResourceValue:&localizedName forKey:NSURLLocalizedNameKey error:NULL];
NSNumber *isPackage = nil;
[url getResourceValue:&isPackage forKey:NSURLIsPackageKey error:NULL];
if ([isPackage boolValue]) {
NSLog(@"Package at %@", localizedName);
}
else {
NSLog(@"Directory at %@", localizedName);
}
}}
为什么localizedName、isPackage和isDirectory在对getResourceValue方法的相关调用之前被设置为nil?这只是过于谨慎还是需要这样做?
当I阅读医生们 for getResourceValue:forKey:error:时,它似乎是多余的:
如果成功填充了值,则返回值YES;否则返回否。 如果未为URL定义所请求的资源值,则讨论值设置为零。在这种情况下,方法仍然返回YES。
我是不是遗漏了什么?
发布于 2011-04-26 03:04:59
在stuff指针类型下将其存档。
下面是一个示例:
#import <Foundation/Foundation.h>
void test(void){
NSString *test1, *test2, *test3;
test1=nil;
// Note: NSString would USUALLY be aloc then init before use...
[test1 isEqual:@"static object string"];
[test2 isEqual:@"static string"];
[test3 isEqual:test1];
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
test();
[pool drain];
return 0;
}现在,在xcode中的test1=nil上放置一个断点,然后运行。在我的机器上,我得到:
test1=(NSString *) 0x0 <nil>
test2=(NSString *) 0x0 <nil>
test3=(NSString *) 0x7fff84db7dd7 Invalid如果您运行它,您将得到EXC_BAD_ACCESS和终止时,它试图执行[test3 isEqual:test1]。您可以使用test1和(意外?)的零值。test2的零值,但使用test3: death中的随机值。
现在,将该行更改为test1=test2=test3=nil;,再次运行它。效果很好。
一个重要的概念:目标中的你可以有效地向零发送信息。 -C。
正如在没有使用时将C指针分配给安全值的良好实践一样,nil在目标C中是一个安全值,直到它被分配给其他东西。对于编写这个例子的程序员来说--可能是肌肉记忆。在特定情况下没有必要,但比随机值更安全。
发布于 2011-04-26 01:55:54
此代码不检查getResourceValue:forKey:error:方法是否实际成功。相反,它假设传递的变量要么设置为零,要么在方法失败时保持不变。这可能不是一个合理的假设;失败时的行为似乎没有记录下来。
如果没有预先初始化,“左不变”将通过使用未初始化的堆栈变量导致未定义的行为。
发布于 2011-04-26 01:51:20
最好的做法是不要让变量不被定义。此外,我认为如果您这样做,您将得到一个编译器警告,如果您只修复它们,就更容易确保您没有错误的警告。
https://stackoverflow.com/questions/5785074
复制相似问题