我正在尝试创建一个方法来检查 null/nil/空字符串,并且我试图让它作为一个类别工作,但没有成功。
我正在使用此代码,基于 this topic 中的答案:
@implementation NSString (NSStringExtension)
- (BOOL)isNullOrEmpty {
return self == nil ||
self == (id)[NSNull null] ||
[@"" isEqualToString:self] ||
[[self stringByReplacingOccurrencesOfString:@" " withString:@""] length] == 0||
[self isEqualToString:@"(null)"]
|| ([self respondsToSelector:@selector(length)] && [(NSData *) self length] == 0)
|| ([self respondsToSelector:@selector(count)] && [(NSArray *) self count] == 0)
|| [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
}
@end
然而,当我尝试使用它时,我得到的是:
NSLog([@"" isNullOrEmpty] ? @"1":@"0"); // prints 1
NSString *s1 = nil;
NSLog([s1 isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([args.itemName isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? @"1":@"0"); // prints 0
这让我感到困惑,我只能假设 iOS5/ARC 的某种组合导致 nil 对象被强制转换为空白字符串/指针。调试器将字符串显示为 0x0,但当我使用我的 isNullOrEmpty 方法时,我得到 false。
最佳答案
return self == nil
这永远不会发生。如果您尝试发送 isNullOrEmpty (或任何其他消息)到 nil ,没有任何反应( objc_msgSend() ,负责消息发送的函数,检查 nil 接收者作为它做的第一件事,然后中止)。
self == (id)[NSNull null]
这也永远不会发生。如果你发送isNullOrEmpty到作为 NSNull 实例的对象,你的方法在这里,这是一个关于 NSString 的方法, 不会被调用。相反,NSNull的版本(可能不存在)将是。
同样,([self respondsToSelector:@selector(count)] && [(NSArray *) self count])永远不会发生。如果对象是一个NSArray , 然后 isNullOrEmpty永远不会运行,因为,这又是一个 NSString 的方法.
相应地,[(NSData *) self length]不做你认为它做的事。 NSString实例确实响应length , 但将对象转换为 NSData不使用 NSData该方法的版本——它仍然以 NSString 结束。 length 的版本,因为对象实际上是一个NSString (转换只发生在编译时;它不能在运行时改变任何东西)。
[self isEqualToString:@"(null)"]
在这里您似乎正在检查 nil再次,但是您被 NSLog 的表示误导了打印时选择 nil :
NSLog(@"%@", nil);
这显示 (null)在控制台中,但这并不意味着对象本身是具有这些字符的字符串。 NSLog只需选择要为 nil 显示的字符串.*
您正在做的几件事需要将其归入 NSObject 的类别中,这样即使对象不是 NSString,该方法也会被调用 .
要检查仅由空格组成的字符串,您只需要与空字符串进行比较 @""修剪空格后:
NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:@""];
// Or:
([trimmedSelf length] == 0);
*更好的是,做 NSLog(@"%@", [NSNull null]);显示器 <null> (尖括号而不是圆括号),在你遇到的前几次很困惑 NSNull .
关于iphone - String isNullOrEmpty 作为类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9709304/
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve
我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod
我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope
有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|
在纯Rubyirb中,不能输入{if:1}。该语句不会终止,因为irb认为if不是符号,而是if语句的开始。那么为什么Rails可以有before_filter接受if作为参数?该指南的代码如下:classOrderunless也会发生同样的事情。 最佳答案 这是一个irb问题,而不是Ruby。bash=>ruby-e"puts({if:1})"bash=#{:if=>1}您可以改用pry。它将正确读取输入。https://github.com/pry/pry 关于ruby-on-rai
>>a=5=>5>>b=a=>5>>b=4=>4>>a=>5如何将“b”设置为实际的“a”,以便在示例中,变量a也将变为4。谢谢。 最佳答案 classRefdefinitializeval@val=valendattr_accessor:valdefto_s@val.to_sendenda=Ref.new(4)b=aputsa#=>4putsb#=>4a.val=5putsa#=>5putsb#=>5当您执行b=a时,b指向与a相同的对象(它们具有相同的object_id).当你执行a=some_other_thing时,a将指向
我如何将像“root_path”这样的Rails路由助手作为类方法添加到像my_model.rb这样的类中?所以我的课是这样的:ClassMyModeldefself.fooreturnself.root_pathendendMyModel.foo以上不起作用,因为ClassMyModel不响应root_path这是我所知道的:我可以使用includeRails.application.routes.url_helpers,但这只会将模块的方法添加为实例方法我试过扩展Rails.application.routes.url_helpers但它没用请随时给我上课:)
我正在努力研究ruby中的函数式编程,但似乎没有太多好的文档。本质上,我正在尝试编写一个具有Haskell类型签名的组合函数:[a]->[a]->(a->a->a)->[a]所以combine([1,2,3],[2,3,4],plus_func)=>[3,5,7]combine([1,2,3],[2,3,4],multiply_func)=>[2,6,12]等等我发现了一些关于使用zip和map的东西,但使用起来感觉真的很难看。什么是最“ruby”的实现方式? 最佳答案 嗯,您说过您了解zip和map,所以这可能没有帮助。但我会