49

我不知道为什么我得到

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;
}
4

5 回答 5

111

在每个 Objective-c 方法中都有两个隐藏变量id selfSEL _cmd

所以

- (void)foo:(id)bar;

是真的

void foo(id self, SEL _cmd, id bar) { ... }

当你打电话时

[someObject foo:@"hello world"]

它实际上是

foo( someObject, @selector(foo), @"hello world")

如果您在 NSAssert 上单击 cmd 以跳转到它的定义,您将看到它是一个宏,它使用您调用它的方法的隐藏 _cmd 变量。这意味着如果您不在 Objective-c 方法中(也许您在“main”中),因此您没有 _cmd 参数,则不能使用 NSAssert。

相反,您可以使用替代的 NSCAssert。

于 2012-03-16T15:18:44.600 回答
31

NSAssert 仅用于 Objective-C 方法中。由于main是 C 函数,请NSCAssert改用。

于 2012-03-16T15:08:48.550 回答
1

尝试更换

NSAssert(x > 11, [NSString stringWithFormat:@"x 应该大于 %d", x]);

NSCAssert(x > 11, [NSString stringWithFormat:@"x 应该大于 %d", x]);

于 2012-03-16T15:01:55.543 回答
0

如果要使用格式参数,则必须将字符串包装在 NSString 类中。这是因为@""它是普通 NSString 的默认构造函数。它现在的编写方式为NSAssert函数提供了第三个参数并与它混淆。

NSAssert(x > 11, [NSString stringWithFormat:@"x should be greater than %d", x]);
于 2012-03-16T14:56:41.070 回答
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.

根据@hooleyhoop @Robertid 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

万岁,它有效!但是,唉,请远离它:)

于 2021-03-04T13:30:49.963 回答