views:

45

answers:

3

I have a cocoa 'category' for adding inflections (pluralize, singularize, etc.) to NSString. The code requires loading a set of regular expression rules and exceptions from a PLIST into dictionaries and arrays, as well as adding manual exceptions from code. I need a way to persist these data structures (as class members) between multiple calls to the inflection code (all instance methods). I attempted:

+ (NSMutableArray *)uncountables 
{
    static NSMutableArray *uncountables = nil;
    if (uncountables == nil) uncountables = [NSMutableArray array];
    return uncountables;
}

However, it appears to fail occasionally. Does a good way of doing this exist? I don't want to subclass NSString if possible. Thanks.

A: 

I think this code is OK. I use the same thing a lot for singletons. But be aware that it is not thread safe this way. Maybe you calling it from different threads?

V1ru8
+5  A: 
[NSMutableArray array];

returns an autoreleased array. Use this instead:

[[NSMutableArray alloc] init];
drawnonward
A: 

As drawnonward already mentioned, [NSMutableArray array]; returns an autoreleased array. But I don't think, it's a good idea to return non-autoreleased array, because it contradicts with Cocoa memory management conceptions - only alloc, copy and new should be released manually. All other initializations are autoreleased.

So, you should just use

interface:
NSArray *a;

...somewhere in a code...
a = [[NSString uncountables] retain];
...

- (void)dealloc {
    [a release];
}

to get properly retained/released objects.

kovpas
No, it's ok for objects with static scope. Think of it as the program asserting ownership of the object. Then the ownership rules are not broken. The ownership rules do not say objects you obtain from methods (except NARC) are *autoreleased*, they say you do not *own* such objects.
JeremyP
Jeremy, I see, thank you!
kovpas