我不得不问这个,因为:我唯一认识到的是,如果断言失败,应用程序崩溃了.这就是使用NSAssert的原因吗?或者还有什么好处呢?将NSAssert放在我在代码中做出的任何假设之上是正确的,比如一个函数应该永远不会接收-1作为参数,但可能是-0.9或-1.1?
我弄清楚为什么会得到
use of undeclared identifier _cmd did you mean rcmd
Run Code Online (Sandbox Code Playgroud)
在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;
}
Run Code Online (Sandbox Code Playgroud) 我正在iOS上开发一个应用程序.我看到有一个叫做的宏NSAssert1.它是为了什么?NSLog和之间的用法有什么不同NSAssert1?
请指导我或建议我可以阅读的教程.
我以为NSAssert不能使用printf说明符,但是这个:
NSAssert(0, @"%@%@", @"foo", @"bar");
Run Code Online (Sandbox Code Playgroud)
像你期望的那样工作:
*** Assertion failure in -[MyClass myMethod], <Path>/MyClass.m:84
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'foobar'
Run Code Online (Sandbox Code Playgroud)
那么,有什么用点NSAssert1,NSAssert2等时NSAssert的作品?
如果这很重要,可以使用Xcode 4.0和iOS 4.3 SDK.(如果没有,我会更新标签.)
stringWithFormat应该返回一个字符串,为什么这个语句不能编译
NSAssert(YES, [NSString stringWithFormat:@"%@",@"test if compiles"]);
Run Code Online (Sandbox Code Playgroud)
什么时候
NSAssert(YES, @"test if compiles");
Run Code Online (Sandbox Code Playgroud)
编译?
NSAssert和之间有什么区别NSCAssert?当我探索他们的实现时,他们看起来非常相似,我找不到我的问题的答案.
我猜想,这也解释之间的差异NSParameterAssert和NSCParameterAssert.
我的项目出了点问题.调试应用程序和应用程序崩溃时,它不会打印断言消息.通常它应该显示如下:
2017-02-05 20:13:54.687 MyPlayground[29372:221950] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.6.21/UITableView.m:1610
2017-02-05 20:13:54.690 MyPlayground[29372:221950] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (10) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus …Run Code Online (Sandbox Code Playgroud) 我经常发现自己断言Objective-C中某个类的对象"isKindOfClass".我是这样做的:
NSAssert([obj isKindOfClass:[AClass class]], @"%@ should be kind of class %@", obj, [[AClass class] description]);
Run Code Online (Sandbox Code Playgroud)
我想知道为它做出捷径的最好方法.我正在考虑定义一个宏,例如:
#define NSClassAssert(obj, class) NSAssert([obj isKindOfClass:class], @"%@ should be of class %@", obj, [class description])
Run Code Online (Sandbox Code Playgroud)
我担心这可能会导致一些令人讨厌的难以处理的编译错误或运行时问题,这样做是否存在根本性的错误,是否有更明智的方法呢?
我想在构建我们的发布iOS二进制文件时禁用在我们的代码行中发生的NSAssert调用,然后我想确认它们被禁用,因为我是超级偏执.我如何确认他们被禁用?
要在我们的发布版本中禁用NSAssert调用,我已将NS_BLOCK_ASSERTIONS = 1(从此处)常量添加到我正在使用xcodebuild进行的命令行发布构建,以便在整个应用程序的构建中阻止NSAsserts,包括构建所有我们使用的静态库.有几十个静态库,尝试验证每个lib的项目文件中都设置了这个标志是太多的维护,所以这种全局方法是首选.它看起来像这样:
xcodebuild -target MyApp -configuration MyReleaseConfig -DNS_BLOCK_ASSERTIONS=1 build
Run Code Online (Sandbox Code Playgroud)
然后确认我们对NSAssert的调用确实被阻止了,这是我正在尝试的,我在寻求建议的地方:我从生成的二进制文件中转储符号表,并为NSAssert宏调用的实际方法进行grepping,像这样:
# Use 'nm' tool to dump symboltable into txt file
/Applications/Xcode.app/Contents/Developer/usr/bin/nm MyApp.app/MyApp > MyApp.symbols.txt
# Search symbols for NSAssertionHandler:
grep "NSAssertionHandler" ./MyApp.symbols.txt
# Output results:
RESULT=$?
if [ $RESULT -eq 0 ]
then
echo -e "** ASSERTION CHECKER FAILED: FOUND 1 OR MORE NSASSERT CALLS IN RELEASE BINARY **"
else
echo -e "** ASSERTION CHECKER SUCCEEDED: NO NSASSERT CALLS IN RELEASE BINARY **"
fi
Run Code Online (Sandbox Code Playgroud)
问题是我仍然看到NSAssertionHandler出现在符号中:
U …Run Code Online (Sandbox Code Playgroud) 我设置了这个NSAssert
NSAssert(isStillLoadingArgument== [[self class] stillLoading],@"Hmm.... we think isStill Loading is false or true and yet stillLoading is true");;
Run Code Online (Sandbox Code Playgroud)
这是我问这个问题的截图:

然后当断言失败时,代码在这里中断:

这是非常烦人的,因为我想在代码中看到断言中断我设置了断言.那么,我该怎么做呢.
Ben答案遗憾的是没有解决问题:
