Skip to content

Instantly share code, notes, and snippets.

@bddckr
Last active December 19, 2015 07:59
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bddckr/5922570 to your computer and use it in GitHub Desktop.
Save bddckr/5922570 to your computer and use it in GitHub Desktop.
Assertion macro that works exactly like NSAssert(), with the modification that a code block will be run if the condition is not met. Helps a lot to prevent repetitions when handling the condition a second time for release code (NSAssert will be stripped by default.) Thanks to @ merowing_ for https://gist.github.com/krzysztofzablocki/5921645 !
// See http://stackoverflow.com/a/257424/283482
// Normally a "do {…} while (0)" is used to prevent the problem described in the linked answer,
// but this would prevent us from using "continue" or "break" in the block parameter.
// The problem is fixed thanks to the "if (1) {…}", doing the same as the "do {…} while (0)".
#define AssertTrueOrRunBlock(condition, block, description, ...)\
if (1) {\
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS\
BOOL check = !!(condition);\
NSCAssert(check, (description), ##__VA_ARGS__);\
if (!check) {\
NSString *format = [NSString stringWithFormat:@"%@%@%@", @"Assertion failure in %s, %s:%d\nCondition not satisfied: %s, reason: '", description, @"'"];\
NSLog(format, __PRETTY_FUNCTION__, __FILE__, __LINE__, #condition, ##__VA_ARGS__);\
block\
}\
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS\
}
- (void)pushScene:(SKScene *)scene withTransition:(SKTransition *)transition {
AssertTrueOrRunBlock(![self.stack containsObject:scene], {
// You can do whatever you want here!
// continue, break work as expected.
return;
}, @"Pushed scene already on stack!");
[super presentScene:scene transition:transition];
[self.stack addObject:scene];
}
// Output:
/*Assertion failure in -[Example pushScene:withTransition:transition:], /…/Example.m:6
Condition not satisfied: ![self.stack containsObject:scene], reason: 'Pushed scene already on stack!'*/
@Tricertops
Copy link

Using this macro turns off code highlighting in whole source file. This is likely a bug in Xcode that I already encountered and it happens always if you put some code inside a macro. Does it happen to others? Is there a solution?

@Tricertops
Copy link

In addition, if you use NSCAssert you prevent retaining self inside of a block (I don't mean your block argument, but ^{}).

@bddckr
Copy link
Author

bddckr commented Jul 7, 2013

@iMartinKiss thanks for pointing me to NSCAssert. I fixed this, the possible wrong use of description and the possible double evaluation of condition.

@yesmar
Copy link

yesmar commented Jul 10, 2013

Docs for NSAssert and NSCAssert indicate that these macros should be be called only for Objective-C or C code, respectively. I think it's probably a bad idea to rely on NSCAssert use in strict Objective-C code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment