我无法弄清楚为什么会得到
use of undeclared identifier _cmd did you mean rcmd
在NSAssert所在的行上。
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int x = 10;
NSAssert(x > 11, @"x should be greater than %d", x);
[pool drain];
return 0;
}
答案 0 :(得分:103)
在每个Objective-c方法中,有两个隐藏变量id self
和SEL _cmd
所以
- (void)foo:(id)bar;
真的是
void foo(id self, SEL _cmd, id bar) { ... }
当你打电话
[someObject foo:@"hello world"]
实际上是
foo( someObject, @selector(foo), @"hello world")
如果你cmd-单击NSAssert跳转到它的定义,你会发现它是一个宏,它使用你调用它的方法的隐藏_cmd变量。这意味着如果你不在Objective-c方法中(也许你在'main'中),因此你没有_cmd参数,你就不能使用NSAssert。
相反,您可以使用替代NSCAssert。
答案 1 :(得分:30)
NSAssert
is only meant to be used within Objective-C methods。由于main
是C函数,请改用NSCAssert
。
答案 2 :(得分:1)
尝试替换
NSAssert(x> 11,[NSString stringWithFormat:@&#34; x应大于%d&#34;,x]);
带
NSCAssert(x> 11,[NSString stringWithFormat:@&#34; x应大于%d&#34;,x]);
答案 3 :(得分:0)
如果要使用格式参数,则必须将字符串包装在NSString类中。这是因为@""
是普通NSString的默认构造函数。它现在的编写方式为NSAssert
函数提供了第三个参数,并与之混淆。
NSAssert(x > 11, [NSString stringWithFormat:@"x should be greater than %d", x]);
答案 4 :(得分:0)
TL;DR - 坚持使用流浪 NSAssert() - 不要在生产中尝试这个
原始代码
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int x = 10;
NSAssert(x > 11, @"x should be greater than %d", x);
[pool drain];
return 0;
}
构建失败
Compiling file hello.m ...
hello.m:9:5: error: use of undeclared identifier '_cmd'
NSAssert(x > 11, @"x should be greater than %d", x);
^
/usr/include/Foundation/NSException.h:450:32: note: expanded from macro 'NSAssert'
handleFailureInMethod: _cmd \
^
hello.m:9:5: error: use of undeclared identifier 'self'
/usr/include/Foundation/NSException.h:451:17: note: expanded from macro 'NSAssert'
object: self \
^
2 errors generated.
基于 explanation by @hooleyhoop @Robert 和
id
self
SEL,
如果我坚持使用以下肮脏的黑客可能适用
NSAssert()
而不是
NSCAssert()
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int x = 10;
// Dirty hack
SEL _cmd=NULL;
NSObject *self=NULL;
NSAssert(x > 11, @"x should be greater than %d", x);
[pool drain];
return 0;
}
构建和运行
Compiling file hello.m ...
Linking tool hello ...
2021-03-04 21:25:58.035 hello[39049:39049] hello.m:13 Assertion failed in (null)(instance), method (null). x should be greater than 10
./obj/hello: Uncaught exception NSInternalInconsistencyException, reason: hello.m:13 Assertion failed in (null)(instance), method (null). x should be greater than 10
万岁它有效!但是,唉,请远离它:)