Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding privately mutable properties behind immutable interfaces in Objective-C

So, what I basically want to ask is whether the following code is safe (not whether it works, because it does). I.e, will the public getter override the synthesized getter of the actionLog property [which is of a different type]?

.h file:

@interface SomeClass : NSObject
- (NSArray*) actionLog;
@end

.m file:

@interface SomeClass ()
@property (strong, nonatomic) NSMutableArray* actionLog;
@end

@implementation SomeClass
...
@end
like image 334
Lukas Kalinski Avatar asked Sep 16 '13 20:09

Lukas Kalinski


2 Answers

This is not only OK, it is exactly why class extensions were created in the first place!

Yes, there will be a single automatically synthesized ivar and pair of getter/setter methods generated as expected.


Sorry -- missed the NSArray vs. NSMutableArray part. No, you can't do that; the types must be the same.

However, you don't want to return your mutable array anyway. First, the caller might modify it (a bug). But, more importantly, the caller will assume that the contents are immutable as implied by the API) and, thus, when that array's contents change out from under the caller, it may cause issue (example; caller can reasonably assume that the result of count will be stable and can be cached).

like image 50
bbum Avatar answered Sep 21 '22 06:09

bbum


By backing the property with a mutable ivar, like this:

.h file:

@interface SomeClass : NSObject

@property (nonatomic, strong) NSArray *actionLog;

@end

.m file:

@implementation SomeClass{
    NSMutableArray* _actionLog;
}

-(void)insertAction:(Action *)action{
    if(!_actionLog){
        _actionLog = [[NSMutableArray alloc] init];
    }
    [_actionLog addObject:action];
}

@end
like image 26
malhal Avatar answered Sep 24 '22 06:09

malhal