Reputation: 15327
I understand that Properties in Objective-C allows us to compactly define:
I would like to use Properties, but it would be nice if I could decouple the data from the getter/setter.
In other words, I like the getter/setter interface of Properties, but I would like to define my own internal representation of data.
For instance, if I were to define MyOwnTime class, I want getters/setters for Properties like hour, date, and minute (as a consumer, I want to be able to set them and get them). However, to save memory in the representation, rather than store date, month, year, hour, minute, second, etc..., I prefer to store secondsSinceEpoch as an unsigned long.
In my situation should I/can I use Properties? How would I do this? Or should I manually roll my own setters and getters?
Upvotes: 1
Views: 255
Reputation: 9543
You can certainly do this. Indeed, it's pretty common. Since the mapping to data is not direct, you cannot synthesise the methods, you have to write the getters and setters manually. But the property will work like any other.
As a simple dummy example:
@interface BytePair
{
UInt16 data;
}
@property UInt8 loByte;
@property UInt8 hiByte;
@end
@implementation BytePair
- (UInt8) loByte
{
return (UInt8) data & 0xff;
}
- (void) setLoByte:(UInt8)lo
{
data = (data & 0xff00) | lo;
}
- (UInt8) hiByte
{
return (UInt8) (data & 0xff00) >> 8;
}
- (void) setHiByte:(UInt8)lo
{
data = (data & 0xff) | (lo << 8);
}
@end
Or whatever. You get the idea.
Upvotes: 2
Reputation: 32681
You can, it's common, and pretty easy to do.
As with a standard property, you don't even need to declare an instance variable for that and can still @synthesize
your property (contrary to what other answers are saying), you simply have to override the setter of the property:
@interface MyObject : NSObject
@property(nonatomic, copy) NSString* myprop; // like any other property
@property(nonatomic, readonly) BOOL hasProp;
@end
@implementation MyObject
@synthesize myprop = _myprop; // optional with latest LLVM compiler, will generate the _myprop instance variable at compile time
// Override default setter for myprop
-(void)setMyprop:(NSString*)newvalue
{
if (_myprop != newvalue)
{
[_myprop release]; // release only necessary if not using ARC
_myprop = [newvalue retain]; // retain only necessary if not using ARC
// And/Or whatever you want your custom setter to do
}
}
// You can override default "-(NSString*)myprop" getter too if you want
// You you can keep the default getter implementation and only override the setter.
// Or vice-versa. It's really up to you
// Another example: we created a @property(readonly) hasProp and implement its getter by ourselves, without any dedicated instance variable
-(BOOL)hasProp
{
return (self.myprop != nil);
}
@end
Upvotes: 0
Reputation: 33359
You don't need to use the @property notation at all. Just do this:
@interface MyObject
- (id)foo;
- (void)setFoo:(id)newFoo;
@end
Then, elsewhere you can do myObject.foo = @"bar";
.
Calling myObject.foo
is exactly the same as [myObject foo]
or [myObject setFoo:foo]
. It has nothing to do with properties, it just happens to be most commonly used for them.
And the @property
syntax is just a formal way of declaring properties allowing you to do more advanced stuff (like nonatomic
). If you're defining your own methods, instead of letting the compiler define them for you, then there isn't much point to using @property
.
If you have ARC disabled, then you might want to look into how to properly memory manage a property, as there are some non-obvious edge cases where you can get into trouble defining your own data storage code.
Upvotes: 0
Reputation: 900
Declare a
@property (nonatomic, assign) sometype somename
in the interface as normal. Then instead of writing
@sythesize somename = _somename
in the implementation, you write
-(sometype)somename {
return whatever;
}
-(void)setSomename(sometype)newValue {
whatever;
}
Upvotes: 1
Reputation: 1661
Of course you can :
@interface MyObject : NSObject
{
int toto;
}
@property(nonatomic, setter=mySetterMethod:, getter=myGetterMethod) int toto;
-(void) mySetterMethod:(int) t;
-(void) myGetterMethod;
Or you can also override the setter and getter default methods, in my case (in the .m file) :
-(int) toto
{
return toto;
}
-(void) setToto:(int) t
{
toto = t;
}
Upvotes: 1