可以定义 NSFound 宏吗?

Posted

技术标签:

【中文标题】可以定义 NSFound 宏吗?【英文标题】:Can one define NSFound macro? 【发布时间】:2016-03-17 15:03:01 【问题描述】:

这听起来像是一个愚蠢的问题,但 Apple 为我们提供了 NSNotFound,但他们为什么不提供一个名为 NSFound 的?有没有一种方法可以自己定义一个 NSFound 宏?

我问这一切的原因是为了让我检查一个字符串是否“包含”某个字符,我必须做双重否定,即

if ([XML rangeOfString:@"error" options:NSCaseInsensitiveSearch].location != NSNotFound)

     //server is down

else

     //server is up

至少对我来说,如果我可以简单地这样做,这会更容易阅读

if ([XML rangeOfString:@"error" options:NSCaseInsensitiveSearch].location == NSFound)

 //server is down

else

 //server is up

如果我想定义 NSFound 或 SAMFound,我该怎么做?

【问题讨论】:

因为 rangeOfString 返回字符串的位置。如果您实际上没有得到找到字符串的位置,那么 NSFound 常量有什么用? @JAL 这没有意义。如果 rangeOfString 返回字符串的位置,那很好,这就是我想要的。如果找不到,请执行其他操作。它会进入 else 块 如果你要为此定义一个宏,考虑到大量可能的“找到”案例,你真的需要做类似#define NSFound(X) (X) != NSNotFound 这样的事情,这意味着你必须像这样使用它NSFound([XML rangeOfString:@"error" options:NSCaseInsensitiveSearch].location) 就个人而言,这也不太可读且不标准! 【参考方案1】:

您的问题实际上与 rangeOfString 之类的设计模式方法有关 - 对两个有效结果(其中有很多)和失败指示(其中有一个)使用单个返回值。在这种情况下,您可以通过与常量NSNotFound 的比较来测试单个失败值,但同样不能通过简单的比较来测试许多可能的值——而是使用您不喜欢的“双重否定”。

如果你觉得它太丑了就换吧……也许吧:

@interface NSString (SamExtras)

- (BOOL) SAMcontainsString:(NSString *)string options:(NSStringCompareOptions)options;

@end

@implementation NSString (SamExtras)

- (BOOL) SAMcontainsString:(NSString *)string options:(NSStringCompareOptions)options

   return [self rangeOfString:string options:options].location != NSNotFound;


@end 

这将允许您使用:

if ([XML SAMcontainsString:@"error" options:NSCaseInsensitiveSearch])

   //server is down

else

   //server is up

没有双重否定。您可以编写一次类别并在所有项目中使用它。

HTH

【讨论】:

完美。这正是我一直在寻找的。谢谢!【参考方案2】:

双重否定不会像在语法中那样在代码中产生后果。

他们提供 not found 的原因,而不是 found 版本,只是 not found 值是单个(假定无效)值,其他所有值都是有效的。因此,定义这个单一的无效值会更简单。

此外,将NSRange 存储在局部变量中以便首先测试有效性然后使用该值更有意义(更有效,避免重复搜索和更少代码):

NSRange range = [XML rangeOfString:@"error" options:NSCaseInsensitiveSearch];
if (range.location != NSNotFound) 
    // Do thing with range
 else 
    // Complain

【讨论】:

我想你是在假设他喜欢将范围用于测试以外的任何事情,但我想很好指出。 @BrandonBuck 是的,我正在做这个假设。 我要做的就是摆脱这种双重否定!= NSNotFound ...这只是重写了我已经知道的内容 @SamB 你问他们为什么不提供NSFound,所以我解释了原因。【参考方案3】:

您的原始测试没有任何问题:

if ([XML rangeOfString:@"error" options:NSCaseInsensitiveSearch].location != NSNotFound) 

如果您只需要知道XML 是否包含字符串@"error",那么该测试可以回答问题,并且是一种完全合法且惯用的提问方式。请注意,即使是文档也告诉您containsString: 只不过是调用rangeOfString:options: 的前线!

如果你真的想知道肯定的版本是什么,那就是测试返回范围的length,看看它是否与@"error"length相同。未找到范围的length0

【讨论】:

以上是关于可以定义 NSFound 宏吗?的主要内容,如果未能解决你的问题,请参考以下文章

可以将逗号和参数传递给 C++ 宏吗?

macro_rules 是常规宏吗?

子目录的cmakelist能直接使用父目录的cmakelist的宏吗

求解:在这里的typedef是一种数据类型吗?那sqlist 和 sqlist L 分别表示啥东西?该程序的名字,类似宏吗

我们可以有递归宏吗?

可以在运行/调试配置中使用 CLion 宏吗?