I tried to assign a value to recordingStatus -
ie recordingStatus = 1
But it doesn't go into the setter which i want some custom code.. what's wrong with my code?
Thanks.
Pier.
In file.h
#property (strong, nonatomic) IBOutlet UILabel *recordingStatusText;
#property (nonatomic)int recordingStatus;
....
In file.m
/* -------------------- Property Setter and Getters ----------------------*/
#synthesize recordingStatus;
- (int) getRecordingStatus {
return recordingStatus;
}
- (void) setRecordingStatus:(int)status
{
[_recordingStatusText setText: #"Just testing!"];
recordingStatus = status;
}
To set and get your property, you should use self.property = newValue;.
OVERRIDING SETTERS AND GETTERS
For getters you don't need to write 'get' in the method signature. So, your getter method uses the wrong name. If you want to override it, the method should be
-(int) recordingStatus {
// Custom Getter Method
return _recordingStatus;
}
In the case of ints, Objective-c wants to see your setter and getter methods in the format of
-(void)setValue:(int)newValue;
-(int)value;
Can you show the code where you call the setter? I'm assuming you're accessing the ivar directly by doing something like this (assuming your ivar is named recordingStatus):
recordingStatus = 1
Instead try this:
self.recordingStatus = 1
Related
I have the following protocol:
#protocol CardTransferFundsDelegate <NSObject>
#property (strong, nonatomic) id<CardTransferFundsView> view;
#end
I have the following in the .h file:
#interface CardTopViewModel : NSObject<CardTransferFundsDelegate>
- (instancetype)initWithVirtualCard:(Card *)card;
#end
In my .m I have the following:
#interface CardTopUpViewModel()
#property (strong, nonatomic) Card *card;
#end
#implementation CardTopUpViewModel
-(instancetype)initWithCard:(Card *)card {
self = [super init];
if(self){
self.card = card;
}
return self;
}
- (id <CardTransferFundsView>)view {
return nil;
}
- (void)setView:(id <CardTransferFundsView>)view {
self.view = view;
}
#end
The issue I have is whenever I call setView it then calls self.view which then calls the getter method and I have a program that just keeps running infinitely.
So my question is, How do I fix this issue, such that the protocol still keeps the property but I am able to get and set the view without having the program run infinitely?
You have implemented the setter, setView, in terms of itself, set.view, so it will recurse until the call stack overflows.
To implement the property specified in your protocol you need three things:
Storage - an instance variable in which to hold the properties value
A setter
A getter
First add an instance variable, say myView:
#implementation CardTopUpViewModel
{
id <CardTransferFundsView>) myView; // storage for view property
}
Now your setter becomes:
- (void)setView:(id <CardTransferFundsView>)view
{
myView = view;
}
And the getter is similarly trivial.
Or of course you can just skip all this and use a property declaration in your #interface which matches that in the protocol and the compiler will provide the storage, setter and getter automagically.
HTH
You should not call self.view = view will call the setter method again and again resulting infinite call. That moto is do not call setter method in with in setter method (setting property will call it again). So Issue in below lines. so view is already a property of viewcontroller. - (void) setView:(id)view is setter method for the view Property. try use another name.
Basically you should be very careful while creating method start with set. Usually try to use method name which starts with any verb as it does some action.
- (void)setView:(id <CardTransferFundsView>)view {
self.view = view;
}
create any property of id <CardTransferFundsView>) with other name and use with in setter method in place of self.view = view.
Is there a way to define a setter method that will run on setting a property like:
i want to call
object.something = 0;
meanwhile in object class i want to achieve something like
- (void)setSomething:(NSInteger)something{
self.something = something;
// some other work too
}
What you want is called property.
you define property in class #interface like:
#interface MyClass()
#property (strong, nonatomic) SomeClass *object;
#end
It will automatically create ivar _object, setter and getter for it.
You can override accessor methods. But if you override both setter and getter, you need to synthesize property like:
#implementation MyClass
#synthesize object = _object;
//setter
- (void)setObject:(SomeClass *)object
{
_object = object;
}
//getter
- (SomeClass *)object
{
return _object;
}
//class implementation
#end
You can do it like this:
#property (nonatomic, weak, setter = setSomething:) UIImageView *photoImageView;
Anyway, setSomething: is the default method for a property named something. You just need to replace self.something with _something, as pointed in the comments.
What is the best practice?
Declare the property as nonatomic
Create custom getter too
Another possibility that I'm not aware of
and why prefer one of this solution rather another.
In most of the cases, you just need to provide implementation for setter and declare the property as nonatmoic. This will generate ivar with underscore prefix and you need to set the value in setter method.
You don't normally need to override getter unless you have special logic in getter or the property need to be atomic.
If you do want to provide getter (along with setter), you may need a backend ivar either by declare it in #implementation{ /*here*/ } or use #synthesize to generate one.
In case for atomic property:
#interface MyClass : NSObject
#property (atomic) id object; // atomic is default attribute
#end
#implementation MyClass
#synthesize object = _object; // to create ivar
- (id)object {
#synchronized(self) { // or use lock / atomic compare-and-swap
return _object;
}
}
- (void)setObject:(id)obj {
#synchronized(self) { // or use lock / atomic compare-and-swap
_object = obj;
}
}
#end
In my .h interface:
#property (nonatomic, strong) UIView *myView;
In my .m:
- (void)setMyView:(UIView *)aView {
_myView = aView; //Use of undeclared identifier "_myView"
}
Why the error?
I'm guessing that in addition to your explicit "setter" method, you also wrote your own explicit "getter" method for the myView property.
When you provide both of the "setter" and "getter" methods for a property, the compiler does not automatically generate an ivar for you. This makes sense since it is possible your property implementation doesn't make use of an ivar.
In this case you must declare your own ivar. Simply do this in the .m:
#implementation MyClass {
UIView *_myView;
}
With that you can reference the _myView ivar in your "setter" and "getter" methods.
Another possibility is that the property was declared in a parent class and you are overriding the "setter" method of the property. In this case you have no access to the ivar. You need to do this:
- (void)setMyView:(UIView *)aView {
[super setMyView:aView];
// do other stuff here
}
add second view as a subview:
[self.view addSubview:anotherView];
Just declaring a property myView in the header file does not create an instance variable called _myView. What you need to add is the following above the #implementation:
#interface ClassName ()
{
UIView *_myView;
}
This is a class extension that allows you to add instance variables and properties without letting other classes know. Then, if you don't already have it, add a synthesize line below the #implementation:
#synthesize myView = _myView;
The synthesize command creates getter and setter methods linked to the _myView instance variable. This also allows you to implement a custom setter without having to implement the getter method.
Hope this helps!
This is the properties declaration:
#property (atomic, weak) zooView* zooView;
This is my custom implementation:
__weak zooView* _zooView;
-(zooView*) getZooView
{
return _zooView;
}
-(void) setZooView:(btBasePinView*)inZooView
{
_zooView = inZooView;
}
I am accessing this property on another thread, on the same class:
[self.zooView imgLoadComplete:self.fullImg];
From some reason, when I access self.zooView I am returned with a nil object.
If I remove the custom setter \ getter, everything works fine.
What might be the reason?
Thanks
The getter for zooView should be -zooView not -getZooView.
To have an instance variable instead of a global, just synthesize it.
#synthesize zooView = _zooView;
-(zooView*) zooView
{
return _zooView;
}
-(void) setZooView:(btBasePinView*)inZooView
{
_zooView = inZooView;
}
This will define an ivar _zooView with your specified getter/setter.