Objective-C - readonly NSMutableArray and NSCoding?

nscoding, objective-c, readonly

Solution

There are a few ways to do this, but one reasonable way is to maintain a private, mutable array, then provide a readonly accessor for the public. Then you just have the public accessor return an immutable copy of the internal array. That would look something like this:

In the .h file:

@interface MyClass : NSObject

@property (readonly) NSArray *publicArray;

@end

In the .m file:

@interface MyClass ()

@property NSMutableArray *privateArray;

@end

@implementation MyClass

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"publicArray"]) {
        keyPaths = [keyPaths setByAddingObject:@"privateArray"];
    }

    return keyPaths;
}


@synthesize privateArray = _privateArray;

- (NSArray *)publicArray { return [self.privateArray copy]; }

@end

You could do without the copy if you feel comfortable counting on the compiler to warn about code that attempts to call mutation methods on the result of `-publicArray` rather than runtime exceptions being thrown. Another caveat is that without a copy, any changes to the private array will be 'seen' even in a previously obtained reference to the supposedly immutable array.

Problem

I have an NSMutableArray, that should be only modified by the owner object (MyObject). so the first attemp was to make it a readonly property. The problem is that this class implements NSCoding, and NSCoding requires the archived objects to be a readwrite property. Then I thought of having a private property (declared in m file), and have a public method that return my private array. But then this would be a reference to the array, and other classes would be able to modify it. My Methods should not return a copy of this array either, because I want the other classes to be able to modify each item= in this array, but not the array itself. QUESTION: How can I have a public property, that is readonly, and at the same time be able to archive and unarchive it?

Original source