Last active
December 19, 2015 07:59
-
-
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 !
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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\ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (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!'*/ |
In addition, if you use NSCAssert
you prevent retaining self
inside of a block (I don't mean your block
argument, but ^{}
).
@iMartinKiss thanks for pointing me to NSCAssert
. I fixed this, the possible wrong use of description
and the possible double evaluation of condition
.
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
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?