ios 实际上,NSAssert 的意义何在?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1375786/
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
What's the point of NSAssert, actually?
提问by Daniel
I have to ask this, because: The only thing I recognize is, that if the assertion fails, the app crashes. Is that the reason why to use NSAssert? Or what else is the benefit of it? And is it right to put an NSAssert just above any assumption I make in code, like a function that should never receive a -1 as param but may a -0.9 or -1.1?
我不得不问这个,因为:我唯一认识到的是,如果断言失败,应用程序就会崩溃。这就是为什么要使用 NSAssert 的原因吗?或者它还有什么好处?将 NSAssert 放在我在代码中所做的任何假设之上是否正确,例如一个永远不应该接收 -1 作为参数但可以接收 -0.9 或 -1.1 的函数?
回答by Daniel
Assert is to make sure a value is what its supposed to be. If an assertion fails that means something went wrong and so the app quits. One reason to use assert would be if you have some function that will not behave or will create very bad side effects if one of the parameters passed to it is not exactly some value (or a range of values) you can put an assert to make sure that value is what you expect it to be, and if it's not then something is really wrong, and so the app quits. Assert can be very useful for debugging/unit testing, and also when you provide frameworks to stop the users from doing "evil" things.
断言是为了确保一个值是它应该是什么。如果断言失败,则意味着出现问题,因此应用程序退出。使用 assert 的一个原因是,如果您有一些函数不会运行或会产生非常糟糕的副作用,如果传递给它的参数之一不完全是某个值(或一系列值),您可以放置一个断言确保该值符合您的预期,如果不是,则说明确实有问题,因此应用程序将退出。断言对于调试/单元测试非常有用,而且当您提供框架来阻止用户做“邪恶”的事情时也是如此。
回答by Mando Escamilla
I can't really speak to NSAssert, but I imagine that it works similarly to C's assert().
我真的不能和 NSAssert 说话,但我想它的工作原理类似于 C 的 assert()。
assert() is used to enforce a semantic contract in your code. What does that mean, you ask?
assert() 用于在您的代码中强制执行语义契约。你问这是什么意思?
Well, it's like you said: if you have a function that should never receive a -1, you can have assert() enforce that:
嗯,就像你说的:如果你有一个永远不应该收到 -1 的函数,你可以让 assert() 强制执行:
void gimme_positive_ints(int i) { assert(i > 0); }
And now you'll see something like this in the error log (or STDERR):
现在您将在错误日志(或 STDERR)中看到类似的内容:
Assertion i > 0 failed: file example.c, line 2
So not only does it safe-guard against potentially bad inputs but it logs them in a useful, standard way.
因此,它不仅可以防止潜在的错误输入,而且还以有用的标准方式记录它们。
Oh, and at least in C assert() was a macro, so you could redefine assert() as a no-op in your release code. I don't know if that's the case with NSAssert (or even assert() any more), but it was pretty useful to compile out those checks.
哦,至少在 C 中 assert() 是一个宏,因此您可以在发布代码中将 assert() 重新定义为无操作。我不知道 NSAssert 是否也是这种情况(或者甚至是 assert()),但是编译出这些检查非常有用。
回答by Abdurrahman Mubeen Ali
NSAssert
gives you more than just crashing the app. It tells you the class, method, and the line where the assertion occurred. All the assertions can also be easily deactivated using NS_BLOCK_ASSERTIONS. Thus making it more suitable for debugging. On the other hand, throwing an NSException
only crashes the app. It also does not tell about the location of the exception, nor can it be disabled so simply. See the difference in the images below.
NSAssert
为您提供的不仅仅是使应用程序崩溃。它告诉您发生断言的类、方法和行。所有断言也可以使用 NS_BLOCK_ASSERTIONS 轻松停用。从而使其更适合调试。另一方面,抛出一个NSException
only 会使应用程序崩溃。它也没有告诉异常的位置,也不能这么简单地禁用它。请参阅下图中的差异。
The app crashes because an assertion also raises an exception, as the NSAssert documentationstates:
应用程序崩溃是因为断言也会引发异常,如NSAssert 文档所述:
When invoked, an assertion handler prints an error message that includes the method and class names (or the function name). It then raises an NSInternalInconsistencyException exception.
调用时,断言处理程序会打印一条错误消息,其中包括方法和类名(或函数名)。然后它会引发一个 NSInternalInconsistencyException 异常。
NSAssert:
NSAssert:
NSException:
NS异常:
回答by Jens Ayton
Apart from what everyone said above, the default behaviour of NSAssert()
(unlike C's assert()
) is to throw an exception, which you can catch and handle. For instance, Xcode does this.
除了上面每个人所说的之外,NSAssert()
(与 C 的不同assert()
)的默认行为是抛出异常,您可以捕获和处理该异常。例如,Xcode 就是这样做的。
回答by Ohad Kravchick
Just to clarify, as somebody mentioned but not fully explained, the reason for having and using asserts instead of just creating custom code (doing ifs and raising an exception for bad data, for instance) is that asserts SHOULD be disabled for production applications.
只是为了澄清,正如有人提到但没有完全解释的那样,拥有和使用断言而不是仅仅创建自定义代码(例如,执行 if 并引发错误数据的异常)的原因是应该为生产应用程序禁用断言。
While developing and debugging, asserts are enabled for you to catch errors. The program will halt when an assert is evaluated as false. But, when compiling for production, the compiler omits the assertion code and actually MAKE YOUR PROGRAM RUN FASTER. By then, hopefully, you have fixed all the bugs. In case your program still has bugs while in production (when assertions are disabled and the program "skips over" the assertions), your program will probably end up crashing at some other point.
在开发和调试时,启用断言以捕获错误。当断言被评估为假时,程序将停止。但是,在为生产进行编译时,编译器会忽略断言代码,实际上使您的程序运行得更快。到那时,希望您已经修复了所有错误。如果您的程序在生产过程中仍然存在错误(当断言被禁用并且程序“跳过”断言时),您的程序可能最终会在其他时间崩溃。
From NSAssert's help: "Assertions are disabled if the preprocessor macro NS_BLOCK_ASSERTIONS is defined." So, just put the macro in your distribution target [only].
来自 NSAssert 的帮助:“如果定义了预处理器宏 NS_BLOCK_ASSERTIONS,则断言将被禁用。” 因此,只需将宏放在您的分发目标中 [only]。
回答by Barry Wark
NSAssert
(and its stdlib equivalent assert
) are to detect programming errors during development. You should never have an assertion that fails in a production (released) application. So you might assert that you never pass a negative number to a method that requires a positive argument. If the assertion ever fails during testing, you have a bug. If, however, the value that's passed is entered by the user, you need to do proper validation of the input rather than relying on the assertion in production (you can set a #define for release builds that disables NSAssert*
.
NSAssert
(及其 stdlib 等效项assert
)用于在开发过程中检测编程错误。在生产(已发布)应用程序中,您永远不应该有一个失败的断言。因此,您可能会断言,您永远不会将负数传递给需要正参数的方法。如果断言在测试期间失败,那么你就有了一个错误。但是,如果传递的值是由用户输入的,则您需要对输入进行适当的验证,而不是依赖生产中的断言(您可以为禁用NSAssert*
.
回答by Lounges
Assertions are commonly used to enforce the intended use of a particular method or piece of logic. Let's say you were writing a method which calculates the sum of two greater than zero integers. In order to make sure the method was always used as intended you would probably put an assert which tests that condition.
断言通常用于强制执行特定方法或逻辑片段的预期用途。假设您正在编写一个方法来计算两个大于零的整数之和。为了确保该方法始终按预期使用,您可能会放置一个断言来测试该条件。
Short answer: They enforce that your code is used only as intended.
简短回答:他们强制您的代码仅按预期使用。
回答by Boon
It's worthwhile to point out that aside from run time checking, assert programming is a important facility used when you design your code by contract.
值得指出的是,除了运行时检查之外,断言编程是您通过契约设计代码时使用的重要工具。
More info on the subject of assertion and design by contract can be found below:
可以在下面找到有关断言和合同设计主题的更多信息:
Assertion (software development)
回答by Robert Hawkey
To fully answer his question, the point of any type of assert is to aid debugging. It is more valuable to catch errors at their source, then to catch them in the debugger when they cause crashes.
要完全回答他的问题,任何类型的断言的目的都是帮助调试。在错误的源头捕获错误,然后在它们导致崩溃时在调试器中捕获它们更有价值。
For example, you may pass a value to a function expects values in a certain range. The function may store the value for later use, and on later use the application crashes. The call stack seen in this scenario would not show the source of the bad value. It's better to catch the bad value as it comes in to find out who's passing the bad value and why.
例如,您可以将一个值传递给期望某个范围内的值的函数。该函数可以存储该值供以后使用,并且在以后使用时应用程序崩溃。在这种情况下看到的调用堆栈不会显示错误值的来源。最好抓住坏值,因为它进来找出谁传递了坏值以及为什么。
回答by Robert Hawkey
NSAssert
make app crash when it match with the condition. If not match with the condition the next statements will execute. Look for the EX below:
NSAssert
与条件匹配时使应用程序崩溃。如果与条件不匹配,则将执行下一条语句。在下面寻找 EX:
I just create an app to test what is the task of NSAssert
is:
我只是创建一个应用程序来测试什么是任务NSAssert
是:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self testingFunction:2];
}
-(void)testingFunction: (int)anNum{
// if anNum < 2 -> the app will crash
// and the NSLog statement will not execute
// that mean you cannot see the string: "This statement will execute when anNum < 2"
// into the log console window of Xcode
NSAssert(anNum >= 2, @"number you enter less than 2");
// If anNum >= 2 -> the app will not crash and the below
// statement will execute
NSLog(@"This statement will execute when anNum < 2");
}
into my code the app will not crash.And the test case is:
进入我的代码,应用程序不会崩溃。测试用例是:
anNum
>= 2 -> The app will not crash and you can see the log string:"This statement will execute when anNum < 2" into the outPut log console windowanNum
< 2 -> The app will crash and you can not see the log string:"This statement will execute when anNum < 2"
anNum
>= 2 -> 应用程序不会崩溃,您可以在 outPut 日志控制台窗口中看到日志字符串:“This statement will execute when anNum < 2”anNum
< 2 -> 应用程序将崩溃并且您看不到日志字符串:“此语句将在 anNum < 2 时执行”