Revision: 8539
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at September 26, 2008 20:33 by zingo
Initial Code
// -------------------------
// header file
// -------------------------
#ifndef RELEASE
#define PFValidateOutlets(obj) PFValidateOutlets_(obj, [NSString stringWithFormat:@"%s", __FILE__], nil)
#define PFValidateOutletsInFile(obj, header) PFValidateOutlets_(obj, [NSString stringWithFormat:@"%s", __FILE__], header)
#else
#define PFValidateOutlets(obj)
#define PFValidateOutletsInFile(obj, header)
#endif
// -------------------------
// .m file
// -------------------------
#import <objc/runtime.h>
void PFValidateOutlets_(id obj, NSString *filepath, NSString *headerFilename)
{
#ifndef RELEASE
if (headerFilename) {
filepath = [[filepath stringByDeletingLastPathComponent] stringByAppendingPathComponent:headerFilename];
}
if (![filepath hasSuffix:@".h"]) {
filepath = [NSString stringWithFormat:@"%@.h", [filepath stringByDeletingPathExtension]];
}
// Parse the outlets
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath]) {
NSString *source = [NSString stringWithContentsOfFile:filepath];
NSArray *classes = [source componentsSeparatedByString:@"@interface"];
NSCharacterSet *spacesSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSCharacterSet *wordTokenizingSet = [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r{}*:;"];
NSCharacterSet *statementTokenizingSet = [NSCharacterSet characterSetWithCharactersInString:@"{}:;/"];
NSCharacterSet *lineSeparatingSet = [NSCharacterSet characterSetWithCharactersInString:@"\n\r"];
for (NSString *classSource in classes) {
NSScanner *scanner = [NSScanner scannerWithString:classSource];
[scanner scanCharactersFromSet:spacesSet intoString:nil];
NSString *className;
// Proceed if the parsed class matches the object's class
if ([scanner scanUpToCharactersFromSet:wordTokenizingSet intoString:&className] &&
[className isEqualToString:NSStringFromClass([obj class])]) {
NSArray *lines = [classSource componentsSeparatedByCharactersInSet:lineSeparatingSet];
for (NSString *line in lines) {
// Skip comment lines
if ([[line stringByTrimmingCharactersInSet:spacesSet] hasPrefix:@"//"]) continue;
NSArray *statements = [line componentsSeparatedByCharactersInSet:statementTokenizingSet];
for (NSString *statement in statements) {
if ([[statement stringByTrimmingCharactersInSet:spacesSet] hasPrefix:@"IBOutlet"]) {
NSString *outletName = [[statement componentsSeparatedByCharactersInSet:wordTokenizingSet] lastObject];
Ivar outletIvar = class_getInstanceVariable([obj class], [outletName UTF8String]);
id outletValue = object_getIvar(obj, outletIvar);
if (outletValue == nil)
NSLog(@"WARNING -- %@'s outlet %@ is nil", className, outletName, outletValue);
}
}
}
}
}
}
#endif
}
// -------------------------
// usage
// -------------------------
- (void)awakeFromNib
{
PFValidateOutlets(self);
// Rest of the code
}
Initial URL
http://www.potionfactory.com/blog/2008/06/15/f-nil-outlets
Initial Description
Initial Title
Parse Header File for Outlets and makes sure that they are set at Runtime
Initial Tags
debug, osx
Initial Language
Objective C