Reputation: 689
I am using objects that conform to an obj c protocol to represent a calculation. There are constants [1], variables [x], and operations [a+b]. All of these objects are immutable (the variable contains a key (to a dictionary) and a default value (to be used if the dictionary doesn't contain a value for the key)).
Since the objects are immutable, I would like to simplify the calculation if possible when an object is initialized. (Note: The variable dictionary is allowed to continuously change, so I am never able to simplify based on the value of a variable, only constants).
For example, a very common use will be to increment a variable by 1: [[x]+1]. When these are nested, I would like to return [[x]+2] from init instead of [[[x]+1]+1] so that that part of the calculation only has to be done once. So far so good.
When both arguments are constants (e.g. [2+2]) it makes sense to just return [4]. But ARC complains about this because [4] is a different class that adheres to the same protocol.
It got me thinking about whether what I want to do is good form. I would normally make them all inherit from a single class (class cluster), but I want to use NSNumber (extended via category) for the constants.
I could move the simplification logic to another method, but that would mean having to allocate extra objects fairly often, and I would have to remember to always call it: [[[MyClass alloc]init]simplifiedCalc].
My options are:
Any thoughts or advice is appreciated.
Upvotes: 1
Views: 134
Reputation: 185671
Instead of doing this work in init, maybe you should just have a convenience method that sets up the un-simplified expression, then goes through and simplifies it and returns the simplified one. Or you could do this as a method on the object itself, e.g.
@protocol Calculation
- (id<Calculation>)simplifiedExpression;
@end
This could return self
if it's already simplified, or construct a new simplified version if not. That way you can still alloc/init your objects as you're doing now, and then simplify them afterwards. You could even make a convenience constructor that does both at once:
+ (id<Calculation>)simplifiedCalculationWithInput:(id)input;
Upvotes: 2