Search code examples
objective-ccocoaencapsulationdeclared-property

Protect from adding object to NSMutableArray in public interface


I want to protect access to NSMutableArray in public interface

I am trying to do this by defining property as NSArray in public interface and as NSMutableArray in private interface like this:

@interface Order : NSObject
@property (readonly, strong, nonatomic) NSArray* comments;
@end

@interface Order()
@property (readwrite, strong, nonatomic) NSMutableArray* comments;
@end

But this doesn't work - so I have to define property in public interface NSMutableArray instead:

@interface Order
@property (strong, nonatomic) NSMutableArray* comments;
@end

The goal is to provide read-only access to comments for API clients and full access to methods like addObject: in the implementation.

So defining goal more clearer:

  1. Client should have access to property as NSArray without ability to access mutation methods.
  2. Client should not have ability to update the comments to point to new value.
  3. The solution must be done without creating extra structures and array copying.

So simply the question was if it's possible to make public definition of property more general (NSArray instead of NSMutableArray).

Is there any other clean way to reach the goal or I have to use NSMutableArray everywhere?

RESOLUTION

After reviewing my original question and answers I realized that I would like to use more generic class NSArray in the public interface and NSMutableArray in the implementation - but it's just not possible for one property. So the answer is not possible.

So I will just use single property with NSMutableArray without any extra desired protection.

But I will also pick the most appropriate answer it might help if you really prefer protection over simplicity and efficiency.


Solution

  • You don't need a public property if all you want is to allow clients to read the array.

    Just create an accessor method that returns a copy of your private mutable array:

    @interface Order : NSObject
    - (NSArray *)allComments;
    @end
    
    @implementation Order ()
    @property (nonatomic, strong) NSMutableArray * comments;
    @end
    
    @implementation Order
    
    @synthesize comments;
    
    - (NSArray *)allComments
    {
        return [[self comments] copy];
    }
    
    @end
    

    This pattern can be seen in e.g., NSView: constraints and subviews are internally mutable, but only exposed for reading via a single method returning a nonmutable array.