سؤال

I get caught out way too many times by creating eg an NSMutableArray* myArray property and then forgetting to assign self.myArray = [NSMutableArray array]; in -init. My app of course never complains in such cases because [self.myArray addObject:foo] is perfectly legal if self.myArray is nil, so I'm left scratching my head and going "double you tee eff".

I realise this is a long shot, but is there an lldb attribute or property specifier that would cause obj-c to ensure that properties are non-nil after completing -init?

هل كانت مفيدة؟

المحلول 2

- (NSMutableArray*) myArray
{
    NSAssert(nil != _myArray);
    return _myArray;
}

You can write this implementation of myArray accessor.

Also you can add in yours class method something like that:

- (void) AssertValid
{
    NSAssert(nil != _myArray);
}

نصائح أخرى

I don't believe there is a compiler flag that will help you, however you could change the semantics of your array access so it goes through your own methods instead of directly to the NSMutableArray.

So instead of

@interface MyClass : NSObject
@property NSMutableArray *array
@end

use:

@interface MyClass : NSObject
- (void)addObject:(id)object;
- (NSUInteger)objectCount;
- (id)objectAtIndex:(NSUInteger)index;
- (void)removeObjectAtIndex:(NSUInteger)index;
@end

and you can add whatever checks you like to those array access methods (as well as lazily creating the array, of course).

However, as you can see, this could be add significant effort just to solve a small issue, and I wouldn't do this myself :)

I am not aware of such mechanism and don't think it exists, because it would make little practical sense as there are many classes whose properties are nil most of the time by design.

It is possible to perform this check using class_copyPropertyList() from objc-runtime and then reading every property by name (for example, using valueForKey:). In simplest case, you would create a category method like [self logNilProperties] on NSObject and call it at the end of init... methods of classes that you want to check.

What you want is not possible. It's a language feature. You can't just change the behavior of the language.

Probably the best solution you can get is to introduce unit tests for the values of your properties. Or asserts:

assert(self.property != nil)

Here is a small piece of code which is used to throw an Exception.

 NSException *exception=[[NSException alloc]initWithName:@"no result" reason:@"array empty" userInfo:nil];
    [exception raise];

The exception can be caught in the AppDelegate file

void exceptionHandler(NSException *exception){

}

Before this method write

NSSetUncaughtExceptionHandler(&exceptionHandler);

in the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Happy Coding :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top