iOS pass NSArray in setter method possible - ios

I try to write a custom setter method but I fail with the error message "Type of property 'pValue' does not match type of accessor 'setPValue:'". The array is passed successfully but I don't understand the the error message.
my .h-file:
#property (nonatomic, assign) double pValue;
- (double)getInverseCDFValue:(double)p;
- (void)setPValue:(NSArray*)aArray;
my implementation:
#synthesize pValue;
- (void)setPValue:(NSArray *)aArray {
double p = [[aArray objectAtIndex:22]doubleValue];
NSLog(#"p is: %f", p); //the value is written successfully
[self getInverseCDFValue:p]; //just calling another method for calculations
pValue = iCFDValue;
}
It works with passing single values but not with arrays. Is this not allowed in setter methods?
Thanks

When you synthesize your property, Xcode is going to generate setter and getter for your property unless your property is read-only. In this case, it's going to create only getter method for you. So, by naming convention, let's say you have a property name toto which type is double, your setter will be
-(void)setToto:(double d).
But what you can do is create another method set your property. But, you need to change your method name to something else. For example,
-(void)setTotoWithNSArray:(NSArray *).

You've defined a property pValue, which is of type double. Objective-C now expects that an accessor and a getter exist, with the names:
- (double)pValue; // Getter
- (void)setPValue:(double)value; // Setter
Either you let Objective-C autogenerate them for you, or you need to provide them explicitly.
Now you are providing a method with the same name, but a different type (NSArray). The type is different, and that's what the error message is telling you: the compiler thinks that the method is setter of your property, but you've given it the wrong type. It tells you because since you violate the expectations, the property cannot be used correctly in some contexts like Key-Value Coding. In almost all cases, what you've done is considered to be a bug.
You could make the pValue property read-only, I think that would make the warning disappear but it still would be bad because the type difference is confusing. Instead, rename the setter with the array argument to something else:
- (void)setPValueFromArray:(NSArray *)anArray;

Related

Using _ to refer to variables? [duplicate]

I am so confused between self and underscore to access the property in Objective c, whenever we create property, its getter-setter automatically generated. So we can access the same property with self.property and same as _property. In my opinion, there shoulb be some difference which i am not getting. PLease tell me with examples.
The underbar (underscore) version is the actual instance variable, and should not be referenced directly. You should always go via the property name, which will ensure that any getter/setter actions are honoured.
So if you code _property = 4, you have directly set the variable. If you code self.property = 4, you are effectively making the method call [self setProperty:4], which will go via the setter (which might do something such as enforce property having a max value of 3, or updating the UI to reflect the new value, for example).
Edit: I though it was worth mentioning that the setter (setProperty) will issue a _property = 4 internally to actually set the instance variable.
when you are using the self.XX, you access the property via the setter or getter.
when you are using the _XX, you access the property directly skip the setter or getter.
Let's say you have a property defined as follows:
#property (nonatomic,strong) NSString* name;
The getters and setters of the name property are automatically generated for you.Now, the difference between using underscore and self is that:
self.name =#"someName"; // this uses a setter method generated for you.
_name = #"someName"; // this accesses the name property directly.
The same applies for getting the name property;

Specifying only getter generates warning b/c no setter, but setter won't compile

I believe the image is pretty descriptive of my problem. If I define only a custom getter as below:
- (UIImage *) secondaryIconImage {
if (_secondaryIconImage) return _secondaryIconImage;
return nil;
}
then I get an error: 'cannot pair a synthesized setter with a user defined getter'. However, if I try to declare the setter as well my code won't compile at all:
- (void) setSecondaryIconImage:(UIImage *)secondaryIconImageVar {
_secondaryIconImage = secondaryIconImageVar;
}
In particular this gives me the compile time error 'Use of undeclared identifier _secondaryIconImage'
I thought perhaps once I declared the setter I would have to synthesize the instance variable myself, so I tried adding:
#synthesize _secondaryIconImage;
This didn't help. What's going on here and how can I fix it?
p.s. I have a custom getter because I will eventually need to do something fancier, but I didn't see a reason to complicate the example since even this basic example is giving me a problem.
As it notes, you cannot define the getter without the setter. (Your getter makes no sense of course, so I assume your actual getter is more complex?)
If you define the getter and the setter, nothing will be synthesized for you (since you've written everything, there's nothing to synthesize), and no ivar will be defined for you. You need to define it yourself if you need it.
You need to explicitly request an ivar via your #synthesize (thanks to Richard Ross for setting me straight):
#synthesize secondaryIconImage = _secondaryIconImage;
Your code asks for a property called _secondaryIconImage, so the ivar would be __secondaryIconImage.

Confused about properties and ivars

I realize that there are already many property vs. ivar questions on here, but after doing a lot of research I can't seem to find a clear answer.
I understand that when you declare a property like the following, that the compiler automatically synthesizes the backing ivar and the two accessor methods for you:
#property NSString *myString;
What still confuses me is, is myString an actual instance variable? The reason I ask this is because you can never access it like this:
NSLog(#"Value of myString is: %#", myString);
You either have to use the backing ivar _myString, or one of the getter methods like [self myString] or self.myString. So I'm confused because normally you could just use the variable name plain and simple.
To top it all off, I've been told that you should not refer to myString as a property, and that the word property should only be used to refer to the two accessor methods that are synthesized for you by the compiler when you use the #property directive.
Would it really be wrong for you to say "I have a property called myString" , and if that is wrong then what would be the correct way to say it?
Any help clearing this up would be greatly appreciated. I've been struggling with solidifying the idea of properties and ivars being different things all day now.
Here are answer of your questions -
is myString an actual instance variable? - No
Would it really be wrong for you to say "I have a property called myString" , and if that is wrong then what would be the correct way to say it? - No its not wrong to call it.
So it looks like what actually confuses you is naming conventions, if you go through the naming conventions behind properties -
When you use the #property syntax to declare properties on an object, as described in “Encapsulating Data,” the compiler automatically synthesizes the relevant getter and setter methods (unless you indicate otherwise). If you need to provide your own accessor method implementations for any reason, it’s important to make sure that you use the right method names for a property in order for your methods to be called through dot syntax, for example.
Unless specified otherwise, a getter method should use the same name as the property. For a property called firstName, the accessor method should also be called firstName. The exception to this rule is for Boolean properties, for which the getter method should start with is. For a property called paused, for example, the getter method should be called isPaused.
The setter method for a property should use the form setPropertyName:. For a property called firstName, the setter method should be called setFirstName:; for a Boolean property called paused, the setter method should be called setPaused:.
Check the developer website for detailed description -
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
I'm pretty much a noob in objective c, but i understand it as follows:
As any other OOP language objective c has instance vars and getters+setters methods.
Basically every getter or setter looks the same, so XCode let you synthesize those automatically using the #property syntax.
In previous versions on XCode you had to declare both the ivar and its #property + #synthesize, but now the compiler does that for you.
This code:
#interface SomeClass : NSObject {
NSString* _myInstanceVar; //declare the ivar
}
#property (non-atomic, strong) myInstanceVar //declare the property+accessors
Is equivalent to this code:
#property (non-atomic, strong) myInstanceVar //declare the ivar+property+accessors
This documentation pretty much sums its up.
Hope i helped in anyway...

what is the difference between local declarations in objective-c [duplicate]

This question already has answers here:
Is there a difference between an "instance variable" and a "property" in Objective-c?
(6 answers)
Closed 9 years ago.
What is the difference between these declarations, lets call them red and orange:
pros, cons?
The red set is properties, and the orange set is instance variables.
A property declaration tells the compiler to define a getter method, and possibly a setter method. (No setter method if the property is readonly.)
In newer versions of Objective C, declaring a property also creates an instance variable that is used to save values for the property. By convention the instance variable has the same name as the property, but with an "_" prefix. There is a way to change the name of the instance variable, but let's ignore that for now.
The property foo:
#property (nonatomic, strong) NSString *foo;
Would have a getter method:
- (NSString *) foo;
and a setter method
- (void) setFoo: (NSString *) foo;
That enables you to use code like this:
NSString *aString = self.foo;
or
NSString *aString = [self foo];
(2 different, equally valid ways of invoking the getter)
And invoking the setter
self.foo = #"a string";
or
[self setFoo: #"a string"];
(2 different, equally valid ways of invoking the setter)
Properties are really useful when you want to create a public interface to get and set values in your class from outside. If you declare a property as "atomic" the compiler adds additional code to the getter and the setter so reads and writes to the property are "thread safe", and can be accessed from background threads.
Before ARC, properties also were a very clean way to manage retains and releases. You declared a property as "retain" and the setter was written to retain the object that was passed in. That's less of an issue in ARC, because the system takes care of retains and releases for you.
It is also possible to write a custom getter or setter method that invokes your own code instead of the compiler-written code. You can use that to do things like log information, send notifications about changes, update labels, etc, etc. You simply add a method body to your .m file that has the same method signature as the getter or setter and the compiler uses that method instead of the automatically generated one.
As I said before, the code:
self.foo = #"a string";
is the same as
[self setFoo: #"a string"];
and invokes the setter method. The setter method sets the internal instance variable _foo.
However, the code
_foo = #"a string";
changes the instance variable directly, without invoking the setter. If you do define a property, you should use it instead of the instance variable.
Objective-c use to be simple...and tedious. You would declare instance variables for a class (the orange) and then you would define (usually) 2 methods for each, one so that an external class could set each instance variable to a new value, and one that returned the ivars value so an external object could read it. Aka, you had to write a getter and setter for each ivar. This was two lines of code in the interface and sometimes around 10 lines of code for the implementation file.
Then came properties, declared with #property. There was much rejoicing and drinking in the streets. These single #property lines told the compiler to write those methods for you, including the correct memory management code and even mutex locking code (depending on what you specified when declaring the #property)
Theres a whole lot of history, but nowadays, with automatic reference counting, it really only makes sense to use #properties in your interface, when you want to make an ivar public, and declare your private ivars in your implementation file.
Lastly, not that #property not only tells the compiler to implement your getter and setter, but it also automatically provides an instance variable with the same name, but prefixed with an underscore (this is only if you have implicit synthesizing of properies enabled...more history)
So, thats the difference. #property tells the compiler to write code for you (essentially). What code it actually writes is modified by all the different ways you can declare a #property.

Custom getter side-effects

Are there side-effects to calling a custom getter with dot notation?
I had been using a synthesized getter in Objective-C via the dot notation, i.e.
tree.fruitnumber
returned the number of fruits in tree. I had to customize the getter (for reasons not pertinent to this question). I wrote it as
-(int) fruitnumber
{
//climb into tree and hand count fruits. Get n;
return n;
}
Suprisingly, the dotted getter still works. Is this legit, or there is a nasty bug (which will infect all my fruits down the road (to the market?)).
Dot notation is really just syntactic-sugar for bracket notation. So both messages are the same:
int x = [self fruitNumber];
int x = self.fruitNumber;
The nice thing is, you can #synthesize your properties and the setter/getter methods will be built for you (depending on your property options, of course) but you can write your own instead and they will be used.
In the case where you are providing your own setters/getters, you can alternatively use the #dynamic propertyName line instead of #synthesize to tell the compiler these are being provided by you.
There's are some side effects that no one has mentioned:
Atomicity - if you don't declare a property as nonatomic, then (by default) it is an atomic property, which means that the value of the property will be full retrieved regardless of what other threads might be doing to mutate the property at the same time. If you have an atomic property and then override the getter or setter, you lose the atomicity (unless you implement it yourself).
Key-Value observation - by using the #synthesized methods, you are ensuring KVO compliance, which makes it very easy to observe values of the object as they change (and be notified of such changes). If you override the synthesized methods, you risk breaking that compliance.
So it is generally safe to override synthesized getters and setters, but there are caveats, and it is very important that you understand what they are so that if/when things break, you know why.
You can specify a custom getter when declaring the property, i.e.:
#property (readwrite, getter=numberOfFruitsCountedByTheCustomGetter) int fruitnumber;
In your implementation, synthesize it as usual:
#synthesize fruitnumber;
Then implement the getter:
- (int) numberOfFruitsCountedByTheCustomGetter {
return fruitnumber;
}
It doesn't matter whether you write the getter or it is synthesized, it gets called when you use the dotted notation (or the bracket notation). This is the way it is supposed to work.
The dot notation is just shorthand for calling the getter or setter method. There is no difference beyond how it looks.
A common side effect used in getters is a lazy getter.
-(id) something {
if ( nil == something ) {
something = ...;
}
return something;
}
A getter does not have to be related to a specific member. It can return the result of a calculation or lookup, or pass on something from a member object.
Progrmr is correct. However I'd consider putting in the #dynamic declaration to explicitly tell the compiler you are creating the getter. Here's a link to the documentation om properties. It's worth a wad if you have had a chance.
http://developer.apple.com/mac/library/iPad/index.html#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html

Resources