Is it possible to decoupling Setters/Getters from data in Objective-C Properties? - objective-c

I understand that Properties in Objective-C allows us to compactly define:
setter
getter
data
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?

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.

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;
}

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;
}

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.

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

Related

Objective-C: Overriding Getter & Setter with Instance Variable (using _) [duplicate]

This question already has answers here:
Error accessing generated ivars when I override setters and getters in Modern Objective-C
(3 answers)
Closed 5 years ago.
I'm learning the Swift programing language and during this I sometimes get in touch with the old Objective-C programming language and its code.
I'm an absolutely beginner and therefore I have some question for better understanding the Setter and Getter.
So, I know that I can create an instance variable through curly braces in the .h file but normally I use properties. These properties are backed by an instance variable and offer automatically a Getter and Setter Method.
Example:
Vehicle .h file:
#interface Vehicle : NSObject
#property int myProperty;
#end
Because I created this property I don't have to declare a Getter and Setter method in the vehicle.m file because they are automatically created by the compiler. So I can create a vehicle-object, set and get the value.
Example
main.m
Vehicle *myvehicle = [[vehicle alloc] init];
[myvehicle myProperty] // myvehicle.myProperty
[myvehicle setMyProperty : 10] // myvehicle.myProperty = 10;
Now I read that it is possible to override the automatically created Getter and Setter method of my created property "myProperty". When declaring my own version of the Getter and Setter I have to declare two methods in the vehicle.h and vehicle.m file. In the vehicle.m file I don't call the object by using the self keyword but by using it's automatically created instance variable (_myProperty). Is it right?
I tried it but alway get an error and I don't know why and what is the point.
Example
Vehicle .h file:
#interface Vehicle : NSObject
#property int myProperty;
-(int) myProperty; //my new Getter method
-(void) setMyProperty: (int)updatedMyProperty; //My new Setter method
#end
vehicle .m file:
#implementation Vehicle
-(int) myProperty {
if (! _myProperty) {
_myProperty = NO;
}
return _myProperty;
}
-(void) setMyProperty: (int)updatedMyProperty {
if (_myProperty == updatedMyProperty) return;
_myProperty = updatedMyProperty;
}
#end
I always get the error "Use of undeclared identifier" and I don't know why. If I understand right I don't have to declare the ivar or its name using #synthesize because the compiler automatically creates the ivar called _myProperty for me. I just have to use #synthesize when I want to change the ivar's name.
I'm not sure why I get stuck and what the point is. Could you explain it?
Thanks in advance!
If you implement all of the accessor methods, the compiler will no longer automatically synthesize the ivar for you. In this case, you have to explicitly do so yourself. E.g.
#synthesize myProperty = _myProperty;
This is only necessary when you have manually implemented all of the accessor methods. The reason is that the compiler is smart enough to know that if you're taking over the accessor methods, you may well not need the ivar, namely that you might be doing something radically different, e.g. computing values from some other property, setting/getting values from some different store, etc. You may want the compiler to synthesize the ivar (in which case you add the above #synthesize statement), but it's equally likely that you've implemented the accessor methods because no backing ivar is needed (in which case you'd omit the above #synthesize statement).
Anyway, staying with your simple example, you get something like:
#interface Vehicle : NSObject
#property (nonatomic) int myProperty; // if you don't write atomic accessor methods, you really should be explicit that this is nonatomic
// as an aside, even if you implement accessor methods, you don't have to declare them here
//
// -(int) myProperty; //my new Getter method
// -(void) setMyProperty: (int)updatedMyProperty; //My new Setter method
#end
And
#implementation Vehicle
// since you implemented all of the accessor properties, you have to manually synthesize the ivar
#synthesize myProperty = _myProperty;
- (int) myProperty {
// do whatever you want here; note, the following doesn't make sense
//
// if (! _myProperty) {
// _myProperty = NO;
// }
return _myProperty;
}
- (void)setMyProperty:(int)updatedMyProperty {
if (_myProperty == updatedMyProperty) return;
_myProperty = updatedMyProperty;
}
#end
Clearly, there's no point in writing these particular accessor methods in the above example, because you're not offering any new functionality, so you wouldn't. You'd just avail yourself of the auto-synthesized accessor methods.
But in those cases that you really need to write your own accessor methods, then you have to explicitly tell the compiler whether you need it to synthesize the ivar for you, too, or not.

What is the difference between the areas where you can declare instance variables in Objective-C? [duplicate]

Ever since starting to work on iOS apps and objective C I've been really puzzled by the different locations where one could be declaring and defining variables. On one hand we have the traditional C approach, on the other we have the new ObjectiveC directives that add OO on top of that. Could you folks helps me understand the best practice and situations where I'd want to use these locations for my variables and perhaps correct my present understanding?
Here's a sample class (.h and .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
#end
and
#import "SampleClass.h"
// 4) what goes here?
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
#implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
#end
My understanding of 1 and 4 is that those are C-style file-based declarations and definitions that have no understanding whatsoever of the concept of class, and thus have to be used exactly how they would be used in C. I've seen them used for implementing static variable-based singletons before. Are there other convenient uses I'm missing?
My take from working with iOS is that ivars have been alost completely phased out outside of the #synthesize directive and thus can be mostly ignored. Is that the case?
Regarding 5: why would I ever want to declare methods in private interfaces? My private class methods seem to compile just fine without a declaration in the interface. Is it mostly for readability?
Thanks a bunch, folks!
I can understand your confusion. Especially since recent updates to Xcode and the new LLVM compiler changed the way ivars and properties can be declared.
Before "modern" Objective-C (in "old" Obj-C 2.0) you didn't have a lot of choices. Instance variables used to be declared in the header between the curly brackets { }:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#end
You were able to access these variables only in your implementation, but not from other classes. To do that, you had to declare accessor methods, that look something like this:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
- (int)myVar;
- (void)setMyVar:(int)newVar;
#end
// MyClass.m
#implementation MyClass
- (int)myVar {
return myVar;
}
- (void)setMyVar:(int)newVar {
if (newVar != myVar) {
myVar = newVar;
}
}
#end
This way you were able to get and set this instance variable from other classes too, using the usual square bracket syntax to send messages (call methods):
// OtherClass.m
int v = [myClass myVar]; // assuming myClass is an object of type MyClass.
[myClass setMyVar:v+1];
Because manually declaring and implementing every accessor method was quite annoying, #property and #synthesize were introduced to automatically generate the accessor methods:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#synthesize myVar;
#end
The result is much clearer and shorter code. The accessor methods will be implemented for you and you can still use the bracket syntax as before. But in addition, you can also use the dot syntax to access properties:
// OtherClass.m
int v = myClass.myVar; // assuming myClass is an object of type MyClass.
myClass.myVar = v+1;
Since Xcode 4.4 you don't have to declare an instance variable yourself anymore and you can skip #synthesize too. If you don't declare an ivar, the compiler will add it for you and it will also generate the accessor methods without you having to use #synthesize.
The default name for the automatically generated ivar is the name or your property starting with an underscore. You can change the generated ivar's name by using #synthesize myVar = iVarName;
// MyClass.h
#interface MyClass : NSObject
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#end
This will work exactly as the code above. For compatibility reasons you can still declare ivars in the header. But because the only reason why you would want to do that (and not declare a property) is to create a private variable, you can now do that in the implementation file as well and this is the preferred way.
An #interface block in the implementation file is actually an Extension and can be used to forward declare methods (not needed anymore) and to (re)declare properties. You could for instance declare a readonly property in your header.
#property (nonatomic, readonly) myReadOnlyVar;
and redeclare it in your implementation file as readwrite to be able to set it using the property syntax and not only via direct access to the ivar.
As for declaring variables completely outside of any #interface or #implementation block, yes those are plain C variables and work exactly the same.
First, read #DrummerB's answer. It a good overview of the whys and what you should generally do. With that in mind, to your specific questions:
#import <Foundation/Foundation.h>
// 1) What do I declare here?
No actual variable definitions go here (it's technically legal to do so if you know exactly what you're doing, but never do this). You may define several other kinds of things:
typdefs
enums
externs
Externs look like variable declarations, but they're just a promise to actually declare it somewhere else. In ObjC, they should only be used to declare constants, and generally only string constants. For instance:
extern NSString * const MYSomethingHappenedNotification;
You would then in your .m file declare the actual constant:
NSString * const MYSomethingHappenedNotification = #"MYSomethingHappenedNotification";
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
As noted by DrummerB, this is legacy. Don't put anything here.
// 3) class-specific method / property declarations
#end
Yep.
#import "SampleClass.h"
// 4) what goes here?
External constants, as described above. Also file static variables can go here. These are the equivalent of class variables in other languages.
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
Yep
#implementation SampleClass
{
// 6) define ivars
}
But very rarely. Almost always you should allow clang (Xcode) to create the variables for you. The exceptions are usually around non-ObjC ivars (like Core Foundation objects, and especially C++ objects if this is an ObjC++ class), or ivars that have weird storage semantics (like ivars that don't match with a property for some reason).
// 7) define methods and synthesize properties from both public and private
// interfaces
Generally you shouldn't #synthesize anymore. Clang (Xcode) will do it for you, and you should let it.
Over the last few years, things have gotten dramatically simpler. The side-effect is that there are now three different eras (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). So when you see the older code, it can be a little confusing. Thus confusion arising from simplicity :D
I'm also pretty new, so hopefully I don't screw anything up.
1 & 4: C-style global variables: they have file wide scope. The difference between the two is that, since they're file wide, the first will be available to anyone importing the header while the second is not.
2: instance variables. Most instance variables are synthesized and retrieved/set through accessors using properties because it makes memory management nice and simple, as well as gives you easy-to-understand dot notation.
6: Implementation ivars are somewhat new. It's a good place to put private ivars, since you want to only expose what's needed in the public header, but subclasses don't inherit them AFAIK.
3 & 7: Public method and property declarations, then implementations.
5: Private interface. I always use private interfaces whenever I can to keep things clean and create a kind of black box effect. If they don't need to know about it, put it there. I also do it for readability, don't know if there are any other reasons.
This is an example of all kinds of variables declared in Objective-C. The variable name indicate its access.
File: Animal.h
#interface Animal : NSObject
{
NSObject *iProtected;
#package
NSObject *iPackage;
#private
NSObject *iPrivate;
#protected
NSObject *iProtected2; // default access. Only visible to subclasses.
#public
NSObject *iPublic;
}
#property (nonatomic,strong) NSObject *iPublic2;
#end
File: Animal.m
#import "Animal.h"
// Same behaviour for categories (x) than for class extensions ().
#interface Animal(){
#public
NSString *iNotVisible;
}
#property (nonatomic,strong) NSObject *iNotVisible2;
#end
#implementation Animal {
#public
NSString *iNotVisible3;
}
-(id) init {
self = [super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
iPrivate = #"iPrivate";
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
_iPublic2 = #"iPublic2";
iNotVisible = #"iNotVisible";
_iNotVisible2 = #"iNotVisible2";
iNotVisible3 = #"iNotVisible3";
}
return self;
}
#end
Note that the iNotVisible variables are not visible from any other class. This is a visibility issue, so declaring them with #property or #public doesn't change it.
Inside a constructor it's good practice to access variables declared with #property using underscore instead self to avoid side effects.
Let's try to access the variables.
File: Cow.h
#import "Animal.h"
#interface Cow : Animal
#end
File: Cow.m
#import "Cow.h"
#include <objc/runtime.h>
#implementation Cow
-(id)init {
self=[super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
//iPrivate = #"iPrivate"; // compiler error: variable is private
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
self.iPublic2 = #"iPublic2"; // using self because the backing ivar is private
//iNotVisible = #"iNotVisible"; // compiler error: undeclared identifier
//_iNotVisible2 = #"iNotVisible2"; // compiler error: undeclared identifier
//iNotVisible3 = #"iNotVisible3"; // compiler error: undeclared identifier
}
return self;
}
#end
We can still access the not visible variables using the runtime.
File: Cow.m (part 2)
#implementation Cow(blindAcess)
- (void) setIvar:(NSString*)name value:(id)value {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
object_setIvar(self, ivar, value);
}
- (id) getIvar:(NSString*)name {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
id thing = object_getIvar(self, ivar);
return thing;
}
-(void) blindAccess {
[self setIvar:#"iNotVisible" value:#"iMadeVisible"];
[self setIvar:#"_iNotVisible2" value:#"iMadeVisible2"];
[self setIvar:#"iNotVisible3" value:#"iMadeVisible3"];
NSLog(#"\n%# \n%# \n%#",
[self getIvar:#"iNotVisible"],
[self getIvar:#"_iNotVisible2"],
[self getIvar:#"iNotVisible3"]);
}
#end
Let's try to access the not visible variables.
File: main.m
#import "Cow.h"
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
#autoreleasepool {
Cow *cow = [Cow new];
[cow performSelector:#selector(blindAccess)];
}
}
This prints
iMadeVisible
iMadeVisible2
iMadeVisible3
Note that I was able to access the backing ivar _iNotVisible2 which is private to the subclass. In Objective-C all variables can be read or set, even those that are marked #private, no exceptions.
I didn't include associated objects or C variables as they are different birds. As for C variables, any variable defined outside #interface X{} or #implementation X{} is a C variable with file scope and static storage.
I didn't discuss memory management attributes, or readonly/readwrite, getter/setter attributes.

Using ObjC class extensions' vars in class category

I declare a class extension interface adding vars to it. Is it possible to access those vars in a category of that class?
Sure - any variable is accessible through the runtime, even if it isn't visible in the #interface:
SomeClass.h
#interface SomeClass : NSObject {
int integerIvar;
}
// methods
#end
SomeClass.m
#interface SomeClass() {
id idVar;
}
#end
#implementation SomeClass
// methods
#end
SomeClass+Category.m
#implementation SomeClass(Category)
-(void) doSomething {
// notice that we use KVC here, instead of trying to get the ivar ourselves.
// This has the advantage of auto-boxing the result, at the cost of some performance.
// If you'd like to be able to use regex for the query, you should check out this answer:
// http://stackoverflow.com/a/12047015/427309
static NSString *varName = #"idVar"; // change this to the name of the variable you need
id theIvar = [self valueForKey:varName];
// if you want to set the ivar, then do this:
[self setValue:theIvar forKey:varName];
}
#end
You can also use KVC to get iVars of classes in UIKit or similar, while being easier to use than pure runtime-hacking.

#property and setters and getters

If I create a #property and synthesize it, and create a getter and setter as well like so:
#import <UIKit/UIKit.h>
{
NSString * property;
}
#property NSString * property;
--------------------------------
#implementation
#synthesize property = _property
-(void)setProperty(NSString *) property
{
_property = property;
}
-(NSString *)property
{
return _property = #"something";
}
Am I correct in assuming that this call
-(NSString *)returnValue
{
return self.property; // I know that this automatically calls the built in getter function that comes with synthesizing a property, but am I correct in assuming that I have overridden the getter with my getter? Or must I explicitly call my self-defined getter?
}
is the same as this call?
-(NSString *)returnValue
{
return property; // does this call the getter function or the instance variable?
}
is the same as this call?
-(NSString *)returnValue
{
return _property; // is this the same as the first example above?
}
There are a number of problems with your code, not least of which is that you've inadvertently defined two different instance variables: property and _property.
Objective-C property syntax is merely shorthand for plain old methods and instance variables. You should start by implementing your example without properties: just use regular instance variables and methods:
#interface MyClass {
NSString* _myProperty;
}
- (NSString*)myProperty;
- (void)setMyProperty:(NSString*)value;
- (NSString*)someOtherMethod;
#end
#implementation MyClass
- (NSString*)myProperty {
return [_myProperty stringByAppendingString:#" Tricky."];
}
- (void)setMyProperty:(NSString*)value {
_myProperty = value; // Assuming ARC is enabled.
}
- (NSString*)someOtherMethod {
return [self myProperty];
}
#end
To convert this code to use properties, you merely replace the myProperty method declarations with a property declaration.
#interface MyClass {
NSString* _myProperty;
}
#property (nonatomic, retain) NSString* myProperty
- (NSString*)someOtherMethod;
#end
...
The implementation remains the same, and works the same.
You have the option of synthesizing your property in your implementation, and this allows you to remove the _myProperty instance variable declaration, and the generic property setter:
#interface MyClass
#property (nonatomic, retain) NSString* myProperty;
- (NSString*)someOtherMethod;
#end
#implementation MyClass
#synthesize myProperty = _myProperty; // setter and ivar are created automatically
- (NSString*)myProperty {
return [_myProperty stringByAppendingString:#" Tricky."];
}
- (NSString*)someOtherMethod {
return [self myProperty];
}
Each of these examples are identical in how they operate, the property syntax merely shorthand that allows you to write less actual code.
return self.property – will call your overridden getter.
return _property; – accesses the property's instance variable directly, no call to the getter.
return property; – instance variable.
EDIT: I should emphasize that you will have two different NSString variables -- property and _property. I'm assuming you're testing the boundaries here and not providing actual production code.
above answer elaborate almost all the thing , i want to elaborate it little more.
// older way
#interface MyClass {
NSString* _myProperty; // instance variable
}
- (NSString*)myProperty; // getter method
- (void)setMyProperty:(NSString*)value;//setter method
#end
the instance variable can not be seen outside this class , for that we have to make getter and setter for it.
and latter on synthesis it in .m file
but now
we only used
#property(nonatomic) NSString *myProperty;
the #property is an Objective-C directive which declares the property
-> The "`nonatomic`" in the parenthesis specifies that the property is non-atomic in nature.
-> and then we define the type and name of our property.
-> prototyping of getter and setter method
now go to .m file
previously we have synthesis this property by using #synthesis , now it also not required it automatically done by IDE.
little addition : this `#synthesis` now generate the getter and setter(if not readonly) methods.

Can I validate a #property value in Objective-C using #synthesized methods?

What it says on the tin: I'd like to use the #property/#synthesize syntax to define a property on my Objective-C 2.0 class, but I want to place restrictions on the range of values allowed in the property. For example:
#interface MyClass : NSObject {
int myValue;
}
#property (nonatomic) int myValue;
Implementation:
#implementation MyClass
#synthesize myValue(test='value >= 0');
Note that the syntax here is just an example. Is this, or something much like it possible? Alternately, what is the literal equivalent of a synthesized setter, so that I can ensure that I use the same object retention rules in my manual setters as is used in a synthesized one.
Assuming your properties are Key-Value compliant (as they would be if you are using #synthesize) you should also implement Key-Value compliant validators. Take a look at Apple's documentation on the matter: http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/Validation.html
The important thing to note is that validation does not happen automatically except when using certain kinds of binding. You either call the validator directly or by calling validateValue:forKey:error:.
You could override the produced setter to call the validator before saving it but if you are using bindings this is probably not what you want to do as the validator will possibly be called more than once for a single modification.
Also note that the validator might change the value being validated.
So lets look at your example (untested, btw. I'm not near a Mac):
#implementation MyClass
#synthesize myValue;
-(BOOL)validateMyValue:(id *)ioValue error:(NSError **)outError
{
if (*ioValue == nil) {
// trap this in setNilValueForKey
// alternative might be to create new NSNumber with value 0 here
return YES;
}
if ( [*ioValue intValue] < 0 ) {
NSString *errorString = #"myValue must be greater than zero";
NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorString
forKey:NSLocalizedDescriptionKey];
NSError *error = [[[NSError alloc] initWithDomain:#"MyValueError"
code:0
userInfo:userInfoDict] autorelease];
*outError = error;
return NO;
} else {
return YES;
}
}
If you wanted to override the synthesised setter and make it do the validation (still untested):
- (void)setMyValue:(int)value {
id newValue = [NSNumber numberWithInt:value];
NSError *errorInfo = nil;
if ( [self validateMyValue:&newValue error:&errorInfo] ) {
myValue = [newValue intValue];
}
}
You can see we had to wrap the integer in an NSNumber instance to do this.
When you use the #synthesize the accessor methods are generated. You can implement your own which will overwrite the generated one.
You can put your own implementation inside the accessor methods, e.g. you can add value checking before assignment and so on.
You can ommit one or the other or both, the ones that you don't implement will be generated because of #synthesize, if you use #dynamic you are specifying that you will provide accessors either at compile or run time.
Accessors will have names derived from the property name myproperty and setMyproperty. The method signatures are standard so it is easy to implement your own. The actual implementation depends on property definition (copy, retain, assign) and if it is read-only or not (read-only doesn't get set accessor). For more details see objective-c reference.
Apple reference:
#synthesize You use the #synthesize
keyword to tell the compiler that it
should synthesize the setter and/or
getter methods for the property if you
do not supply them within the
#implementation block.
#interface MyClass : NSObject
{
NSString *value;
}
#property(copy, readwrite) NSString *value;
#end
#implementation MyClass
#synthesize value;
- (NSString *)value {
return value;
}
- (void)setValue:(NSString *)newValue {
if (newValue != value) {
value = [newValue copy];
}
}
#end