I want to make a readonly instance of a class in Objective C. I have a vector class which is basically floats for x and y position and some methods. In a lot of cases I need a (0, 0)-vector so I was thinking instead of allocating a new one each time that I would have a shared zero vector, something like this:
// Don't want to do this all the time (allocate new vector)
compare(v, [[Vector alloc] initWithCartesian:0:0]);
// Want to do this instead (use a shared vector, only allocate once)
compare(v, [Vector zeroVector]);
// My attempt so far
+ (Vector *)zeroVector {
static Vector *sharedZeroVector = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedZeroVector = [[self alloc] initWithCartesian:0:0];
});
return sharedZeroVector;
}
// The problem
v.x = 3;
This works fine, except that the zero vector is not readonly, which feels kind of silly. As a note I would like to mention that this is more of a want-to-know-how-to kind of question than an actual problem, I don't know if it will make some actual difference.
The common solution is having all instances immutable (see NSNumber, NSDecimalNumber etc.), possibly having a second mutable class (NSString vs NSMutableString or NSArray vs NSMutableArray).
Depends on how your standard vector should work. If you never want to set x and y via property you could just make them readonly:
@property (nonatomic, readonly) NSInteger x;
@property (nonatomic, readonly) NSInteger y;
If some of your vectors should be readwrite you can create a readonly class Vector and derive a class MutableVector:
@interface Vector : NSObject
@property (nonatomic, readonly) NSInteger x;
@property (nonatomic, readonly) NSInteger y;
@end
@interface MutableVector : Vector
@property (nonatomic) NSInteger x;
@property (nonatomic) NSInteger y;
@end
You would then use Vector for zeroVector and MutableVector for all others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With