xcode 为什么将 NSString 对象传递给 XCTAssertTrue 的“格式”参数会导致构建错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19828591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:16:17  来源:igfitidea点击:

Why does passing an NSString object to the "format" parameter of XCTAssertTrue cause a build error?

iosobjective-cxcodemacosxctest

提问by akivajgordon

In attempting to use XCTest to test my application, I get a build error when doing the following:

在尝试使用 XCTest 测试我的应用程序时,我在执行以下操作时遇到构建错误:

#import <XCTest/XCTest.h>

@interface MyTests : XCTestCase

@end

@implementation MyTests

- (void)testExample
{
    NSString *str = @"foo";
    XCTAssertTrue(YES, str); // Parse issue: Expected ')'
}

@end

but I do notget a build error if I do this:

但如果我这样做,我不会收到构建错误:

#import <XCTest/XCTest.h>

@interface MyTests : XCTestCase

@end

@implementation MyTests

- (void)testExample
{
    XCTAssertTrue(YES, @"foo"); // this is just fine...
}

@end

The build error that I get is:

我得到的构建错误是:

Parse issue: Expected ')' 

and it puts an arrow under the "s" in "str".

并在“str”中的“s”下方放置一个箭头。

I discovered that I can remedy this by changing

我发现我可以通过改变来解决这个问题

XCTAssertTrue(YES, str)

to

XCTAssertTrue(YES, @"%@", str)

but I just cannot figure out why that makes a difference. Can somebody please explain why this is so?

但我就是不明白为什么这会有所作为。有人可以解释一下为什么会这样吗?

回答by Itai Ferber

The XCT...macros are written to accept format strings — the strings themselves are optional (so that writing XCTAssertTrue(YES)is valid), but they must be constant strings. You cannot pass objects into the macro without having a format string, which is why XCTAssertTrue(YES, @"%@", str)works, but, say, XCTAssertTrue(YES, str)or XCTAssertTrue(NO, nil)wouldn't.

XCT...宏被写入接受格式字符串-字符串本身是可选的(这样写XCTAssertTrue(YES)是有效的),但必须是常量字符串。你不能在没有格式字符串的情况下将对象传递到宏中,这就是为什么XCTAssertTrue(YES, @"%@", str)有效,但是,XCTAssertTrue(YES, str)或者XCTAssertTrue(NO, nil)不会。

回答by Greg Parker

Deep inside the implementation, the code does this:

在实现的深处,代码是这样做的:

    @"" format

If formatis a constant string literal, the compiler concatenates the strings. If formatis anything else, you get a compiler error.

如果format是常量字符串文字,编译器将连接字符串。如果format是其他任何事情,您会收到编译器错误。

回答by Jonathan Mitchell

Passing predefined text into the assertion is sometimes desirable so:

有时需要将预定义文本传递到断言中,因此:

XCTAssertTrue(YES, @"foo"); // this is just fine...

As is this

就像这个

#define FOO @"foo"
XCTAssertTrue(YES, FOO); // this is just fine too...

So I do stuff like:

所以我做这样的事情:

#define DBUEqualityTestFailed @"Equality test failed"

// test
DBNumber *n1 = [@((int)1) dbNumberFromIntValue];

XCTAssertTrue(*(int *)[n1 valuePointer] == 1, DBUEqualityTestFailed);
XCTAssertTrue([n1 valuePointer] == [n1 valuePointer], DBUEqualityTestFailed);
XCTAssertTrue(*(int *)[n1 valuePointer] == *(int *)[n1 valuePointer], DBUEqualityTestFailed);