How to override #synthesized getters? - iphone

how to override a property synthesized getter?

Just implement the method manually, for example:
- (BOOL)myBoolProperty
{
// do something else
...
return myBoolProperty;
}
The compiler will then not generate a getter method.

Inside of your property definition you can specify getter and setter methods as follows:
#property (nonatomic, retain, getter = getterMethodName, setter = setterMethodName) NSString *someString;
You can specify the getter only, the setter only, or both.

Just implement your own getter and the compiler will not generate one. The same goes for setter.
For example:
#property float value;
is equivalent to:
- (float)value;
- (void)setValue:(float)newValue;

I just want to add, I was not able to override BOOL property with getter/setter, until I add this :
#synthesize myBoolProperty = _myBoolProperty;
so the complete code is :
in header file :
#property BOOL myBoolProperty;
in implementation file :
#synthesize myBoolProperty = _myBoolProperty;
-(void)setMyBoolProperty:(BOOL) myBoolPropertyNewValue
{
_myBoolProperty = myBoolPropertyNewValue;
}
-(BOOL) myBoolProperty
{
return _myBoolProperty;
}

Related

Using objective C++, can you create a property that is a C++ class and the getter returns a reference

I want to do this but have not seen it anywhere.
#property (nonatomic) MyCPPClass &myInstance;
I need it to write a getter that returns a reference and not a copy.
- (MyCPPClass &)myInstance {
return _myInstance;
}
Or can it only be done with an iVar and writing my own getter and setter.
You may use a private instance variable for that:
#interface MyObjCPPClass
#property (nonatomic) MyCPPClass &myInstance;
#end
#implementation MyObjCPPClass {
MyCPPClass _myInstance;
}
- (MyCPPClass &)myInstance {
return _myInstance;
}
- (void)setMyInstance:(MyCPPClass &)instance {
_myInstance = instance;
}
#end

check if a particular property in a class (not an instance of class) exist

i have to create a class method and i need to check if a particular string correspond to a property in a class.
example:
#interface aClass
#property (nonatomic, strong) aType *property1;
#end
in other class:
+ (X*)createXwithProperty:(NSString*) aProperty
{
if([aClass haveProperty:aProperty])
{
return create(X);
}
else return nil;
}
How can i achieve this ?
Since it is a #propery it has getter and setter method.
In your example:
#property (nonatomic, strong) aType *property1;
Getter method should be called property1 as your property, so you can check if your class instance responds to that selector like this:
Convert NSString to selector:
SEL selector = NSSelectorFromString(#"property1");
if ([aClassInstance respondsToSelector:selector]) {
NSLog(#"RESPONDS");
}
Sorry, I was to fast on answering. I see now that you want to check if class has specific property, but you don't have a class instance.
To see if class has specific property use this (basically, the principle it is the same as with class instances :) ):
SEL selector = NSSelectorFromString(#"property1");
if ([aClassNotInstance instancesRespondToSelector:selector]) {
NSLog(#"RESPONDS");
}

Setter method giving underscore error when I have a getter method

I use setters quite often. This is the code I have for this one:
.h:
#property (nonatomic, strong) NSDate *lastSyncDate;
.m:
-(void)setLastSyncDate:(NSDate *)lastSyncDate {
_lastSyncDate = lastSyncDate;
//Do something
}
Then I put in a getter method:
-(NSDate *)lastSyncDate {
//Something happens
return lastSyncDate;
}
And then the _lastSyncDate identifier gives out an unidentified identifier error.
I'm not sure why this is happening?
It should be
return _lastSyncDate;
in the getter method. By default, the synthesized instance variables have a leading underscore
(and you already use that in the setter method).
Also, if you provide both setter and getter method, you have to synthesize the
property explicitly:
#synthesize lastSyncDate = _lastSyncDate;
The same would happen if you provide the getter for a read-only property.
The property is synthesized by the compiler only if a
required accessor method is missing.

Property with no iVar and getter method?

I spotted this today and just want to verify my understanding of what is going on. "prefixName" is a readonly property that uses a getter method to directly pass a value back, there is no iVar storing the result on the PR_ViewController object. Also if the property was not readonly adding a setter still would not work as there is no iVar to set.
Created: [Meth] prefixName
By contrast "characterName" works the usual way for a property, adding a getter, a setter and an iVar.
Created: [Meth] characterName
Created: [Meth] setCharacterName
Created: [iVar] characterName
.
#interface PR_ViewController : UIViewController
#property (nonatomic, readonly) NSString *prefixName;
#property (nonatomic, retain) NSString *characterName;
.
#implementation PR_ViewController
#synthesize characterName;
- (NSString *)prefixName {
return #"FRED";
}
You are not required to synthesize accessors - you can perfectly well write them yourself, which is what is done in your example.
Further, a read-only property does not have to be based on an ivar, but can be computed, based on other ivars or properties. This can be useful if you use bindings to display values in the UI that are derived from other properties, provided you like that coding style.
Here is a simple example of a readonly property computed based on two other properties:
Header file:
#property double width;
#property double height;
#property (readonly) double area;
Implementation:
#synthesize width, height;
- (double)area
{
return width*height;
}
+ (NSSet *)keyPathsForValuesAffectingArea
{
return [NSSet setWithObjects:#"width", #"height", nil];
}
Now, whenever either one of width or height changes, the area property changes, too, and its changes are propagated to its listeners (thanks to keyPathsForValuesAffectingArea.)
You can also see the fullName example in this doc.

Setter method not being called

I have this code:
.h
int cellsPerRow;
#property int cellsPerRow;
.m
#synthesize cellsPerRow;
-(void)init {
...
cellsPerRow = 4;
}
-(void)setCellsPerRow:(int)cellsPerRowLocal {
cellsPerRow = cellsPerRowLocal;
....
}
But the setter method isn't being called. Any ideas why?
You are assigning to the variable instead of the property. Instead of:
cellsPerRow = 4;
You need to do either:
self.cellsPerRow = 4;
or
[self setCellsPerRow:4];
The former is transformed by the compiler into the later, so they are equivalent.
The property and synthesize create the setter and getter methods for you. In essence what you are doing is actually override the methods that were created for you in the first place.
Don't do that. Just use dot notation, like so, self.cellsPerRow = cellsPerRowLocal. This will set your cellsPerRow ivar to whatever you want it to be in cellsPerRowLocal.
In you header file:
int cellsPerRow;
#property (nonatomic, retain) int cellsPerRow;
In your implementation file:
#synthesize cellsPerRow;
- (void) inThisMethodYouSetcellsPerRow {
cellsPerRowLocal = ... ;
self.cellsPerRow = cellsPerRowLocal;
}