I've created a macro that, if compiling in debug mode, will check to make sure the method has been called by a subclass with the same name (to stop external classes from calling it). If that is not the case, it will throw an exception:
#ifdef DEBUG
#define CHECK_INHERITANCE() \
do { \
NSString *this = [NSThread callStackSymbols][0]; \
NSString *parent = [NSThread callStackSymbols][1]; \
NSError *error = NULL; \
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[\\w+ ((\\w+:)+)\\]" options:NSRegularExpressionCaseInsensitive error:&error]; \
NSTextCheckingResult *resultThis = [regex firstMatchInString:this options:0 range:NSMakeRange(0, this.length)]; \
NSString *strThis = [this substringWithRange:[resultThis rangeAtIndex:1]]; \
NSTextCheckingResult *resultParent = [regex firstMatchInString:parent options:0 range:NSMakeRange(0, parent.length)]; \
NSString *strParent = [parent substringWithRange:[resultParent rangeAtIndex:1]]; \
if(![strThis isEqualToString:strParent]) [NSException raise:NSGenericException format:@"Must be called from a subclass"]; \
} while (0);
#else
#define CHECK_INHERITANCE() //
#endif
I tested it and it works, but the NSException
it throws doesn't give me any stack trace that would hint at why it crashed, nor does it show the message "Must be called from a subclass". I just get "0 __kill
" on the main thread and a bunch of lines of assembler. How can I get it to throw me a more useful exception? Am I doing it wrong?