Setter method giving underscore error when I have a getter method - iphone

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.

Related

Assigning Value to dynamic property causes a crash

This is the as to what I am trying to implement in this program
#interface settings : CBLModel
#property (copy) NSString* foo;
- (instancetype) initInDatabase: (CBLDatabase*)database withAllValues:(NSDictionary*)gameDic ChannelId:(NSString*)chann_id;
In .m file I am using this...
#implementation settings
#dynamic foo;
- (instancetype) initInDatabase: (CBLDatabase*)database
withAllValues: (NSDictionary*)gameDic ChannelId:(NSString*)chann_id
{
NSParameterAssert(gameDic);
self = [super initWithNewDocumentInDatabase: database];
if (self) {
self.foo=#"value";//this is where it crashes
}
return self;
}
-(void)setfoo:(NSString *)foo{
foo=[foo copy];//tried doin this but the value is not assigned
}
I am trying to set value of a dynamic property which results in the crash.. I need to use dynamic as I want to reflect it on server and using synthesize doesn't do that.
First of all, your property is in lowercase foo, and the dynamic declaration
in uppercase Foo. This could be a cause for problems. But assuming that this
was just a typo,
#dynamic foo;
tells the compiler that it should not synthesize getter and setter methods for the property.
It is a "promise" that the required accessor methods will somehow be provided at runtime.
Since you don't provide a setter method,
self.foo = #"abc";
must crash at runtime.
So unless you have a definite reason, you can just remove the #dynamic declaration,
and the compiler will synthesize getter, setter, and instance variable, if necessary.
A better answer might be possible if you explain what you are trying to achieve.
Remark: If your custom setFoo: goes into an infinite loop then you probably use the
property setter inside the setter method, instead of accessing the instance variable directly.
A simple example:
-(void)setFoo:(NSString *)foo
{
// wrong: self.foo = [foo copy];
_foo = [foo copy];
}
UPDATE: The above answer was written before I knew that "settings" is a subclass of
"CBLModel" from "Couchbase Lite". I do not have experience with that framework, but from
reading the documentation it seems to me that #dynamic foo; is indeed correct in this case,
and setFoo: should not be implemented in the subclass, because
the Couchbase framework creates the necessary accessor methods at runtime.
The only possible error I can see is that the custom initializer should call
self = [self initWithNewDocumentInDatabase: database];
instead of
self = [super initWithNewDocumentInDatabase: database];
Try to change #property(copy) NSString* foo; with #property (nonatomic, strong) NSString *foo;
#dynamic property indicates that implementation of setter and getter will be provided by some underlying code in runtime. It is commonly used in NSManagedObject subclasses of Core Data. There is no underlying code to manage your #dynamic properties if your object is a subclass of NSObject, so you are responsible for implementing setters and getters. Change #dynamic to #synthesize to let the compiler create appropriate setter and getter for you.
UPD: As of the latest compiler you may omit #synthesize as Martin R said.

Releasing iVar with public readonly getter

How do I release memory with ARC using a public readonly attribute? Say I have the following code:
SomeClass.h:
#interface SomeClass : NSObject
#property (readonly, nonatomic, strong) NSArray* someArray;
#end
SomeClass.m:
#import "SomeClass.h"
#implmentation SomeClass
#synthesize someArray = _someArray;
- (void)dealloc {
self.someArray = nil; //causes compiler error because of public readonly
_someArray = nil; //does this correctly release the object?
}
#end
It's my understanding that the way you dealloc in ARC is setting all strong properties to nil using the getter method. Since the variable is publicly declared "readonly", then the compiler will not allow the use the getter method. And from what I know of ARC, setting a iVar to nil does to call release in the underlying code. Is this correct?
Thanks for the help!
When you set it to nil you are telling the compiler that you have no further reference to it and it will add the release for you. The fact that its readonly just means outside classes can't access it but its still a strong reference so you will need to get rid of that reference for it to be properly released. You can't access it with self.someArray because using self is accessing it through the property name and not the member variable.

Define #property in Protocol

I have a number of UIViewController subclasses and I want them to share the same property called session which handles a "is logged in" state.
I know that I could use a parent class but this is very explicit and so I was wondering if I could "enforce" the session property via a shared protocol.
I have never seen an explicit property defined in a protocol (obviously you could define the setter and getter), so is defining a property inside a protocol an advisable pattern?
#property can also appear in the declaration of a protocol or category.
Stated in the official apple documentation. So no problem there.
Yes, using a protocol it's possible to add a property:
#protocol MyProtocol <NSObject>
#property (nonatomic, retain) NSFoobar *baz;
#end
And #synthesize baz; in every class that adopts this protocol (or you can mark the declared property as optional using the #optional keyword).
You can have properties in a protocol, provided every class that conforms to your protocol have a corresponding #synthesize for that property, or provide a getter and setter.
In .h file:
#property(nonatomic,strong)UILabel *mylabel;
In .m file:
#synthesize mylabel = _mylabel;
compiler will create getter and setter for mylabel.
Ex ->
-(void)setMylabe:(UILabel *) mylabel { //setter
}
-(UIlabel*)mylabel { // getter
}

How to override #synthesized getters?

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

#property #synthesize

What do #synthesize and #property do in Xcode? Please provide an explanation in really simple terms?
You asked for simple terms:
#property declares a property in your
class header
#property (nonatomic, retain) NSString *myString;
#synthesize creates your setter and
getter for your property (accessor
methods)
Without synthesize you have to write
your own setter and getter
implemention, like getMyString or
setMyString (capitalize the first
character of your property)
Sam: Just an advice: http://www.cocoadevcentral.com/d/learn_objectivec/ is a pretty solid resource to learn about basics like properties.
Good Luck!
Properties and synthesized accessors are new features in Objective-C 2.0.
When you declare a #property you declare somewhat an instance var. Then you #synthesize accessor methods (i.e. getter and setter) for that property.
There are also #dynamic accessors if you're interested.
You should really do your homework on this. Apple has nifty pdf for that.
Think of all objective-c magic as just a "smarter macro", like a "smarter #define statement"
#property if you notice is always in the h file,
#synthesize is always in the m file.
So in the background
#property (whatever) NSString *myString;
becomes a declaration of 2 methods and a private variable;
void set_myString:(NSString *) str;
(NSString*) get_myString;
declarations in the header file
to make them do something their implementation is added into m file when you type in
#synthesize myString;
which becomes something like
void set_myString:(NSString *)str
{
myString = str;
}
(NSString *) get_myString
{
return (myString);
}
But it's smarter than this
depending on if you say "retain" "strong" or "weak"
it will either just return the pointer to the myString or it will copy the myString into a new object
So all of this is done automatically by a compiler just by reading your declarations.
Which is quite useful and saves a lot of time
By default all our variables are Private so we can't acess out of the class.
if we want to use our instance variable in out of the class.
When you declare a #property you declare somewhat an instance var. Then you #synthesize accessor methods (i.e. getter and setter) for that property.
There are also #dynamic accessors if you're interested.
it simply sets the property's setter variable name in it's own class.
For example lets say I have this: #property (nonatomic, copy) NSArray* viewControllers;
Well if i want to access the setter _viewController i wouldn't set a synthesize variable.
but if i want to access the viewController variable by the name viewController instead of _viewController, I would do #synthesize viewController;.
If I wanted to use it as a completely different name I could do this #synthesize viewControllers = viewControlololer; but that's only setter. As you will notice [self viewControllers] only works and not [self viewControlololer];
So I don't understant why everyone writes sets the "setter and getter" of a property. It doesn't change the getter variable at all... unless that means [self viewController] is aware of viewControlololer (obviously).
Actually properties are synthesized, either implicitly or explicitly. Properties are implicitly synthesized. So there's no need to use synthesized unless you wanna change the name of the variable to something different than _property_name.
There are other use cases, for example if you don't want an instance variable to back your property.
Properties are explicitly synthesized by using the #synthesized directive.
(Answer extracted from the Big Nerd Ranch guide)