How to do pointer work with accessor methods in Objective-C - objective-c

Basic problem statement:
I have a very good reason for doing some pointer fanciness in an app where I need to pass a decimal by reference.
So I have a class which stores many a decimal, so let's say is has a property as such:
#property (nonatomic) double myDecimalValue;
I want to pass it by reference to some other class.
[someOtherObject sendMyDecimalByReference:&myDecimalValue];
But, a problem emerges! The way that actually has to be written (because it's a property) is
[someOtherObject sendMyDecimalByReference:&decimalOrigin.myDecimalValue];
This fails to compile in objective-c
I get around it by writing the following
- (double *) myDecimalValueRef;
[someOtherObject sendMyDecimalByReference:[decimalOrigin myDecimalValue]];
Except I have dozens of these decimals and I don't want to write that stupid wrapper function for every value.
Is there a shorthand way to do this in Objective-C using just the Getter functions?
Let's just assume I have a great reason for not using NSNumber.
Thanks!

Can you use and access an instance variable directly instead of a property? Then it would work the same way as a C struct member...
#interface SomeClass : NSObject
{
#public
double myDecimalValue;
}
// Keep the getter or not, assuming you synthesize it in a way that uses the
// myDecimalValue ivar
#property (nonatomic) double myDecimalValue;
#end
Then you could access it this way:
[someOtherObject sendMyDecimalByReference:&decimalOrigin->myDecimalValue];
Of course, the robustness is limited, someOtherObject has to remain a valid object when you actually dereference the value, and if you have subclasses/superclasses, you will have to take this design into account...

While far from ideal, you could make the ivars public. I hate even saying that, but it is a possible solution.
Another option is to create a pair of properties for each decimal. Create regular property and also a reference property:
#interface Foo : NSObject
double _myDecimal;
#property (nonatomic, assign) double myDecimal;
#property (nonatomic, assign) double *myDecimalRef;
#end
#implementation Foo
#synthesize myDecimal = _myDecimal;
- (double *)myDecimalRef {
return &_myDecimal;
}
- (void)setMyDecimalRef(double *)val {
_myDecimal = *val;
}
#end
Now you can things like:
[someOtherObject sendMyDecimalByReference:decimalOrigin.myDecimalRef];
Or something like this:
*decimalOrigin.myDecimalRef = 3.14;

Have you looked at the NSValue class? It allows you to pass pointers around as objects.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSValue_Class/Reference/Reference.html

Related

Simple Class Extension / Inheritance Clarification

I've been writing Objective-C for a few years now, and decided to go back and learn the very basics to help me write even better code. I'm trying to learn all about instance variables, inheritance and class extensions. I've been reading up on all three, but there is one thing that boggles my mind. I have a simple app that contains 2 classes, Person, Male (inherits from Person), and of course Main (which imports the Male class, therefore being able to access the instance variables found in both Person and Male).
The code is simple, and for the sake of space I won't post all of it. Basically Main takes these variables and plays around with them. This is the part that is boggling my mind:
#interface Person : NSObject {
float heightInMeters;
int weightInKilos;
}
#property float heightInMeters;
#property int weightInKilos;
#end
When I delete the brackets and variable declarations, leaving it like this:
#interface Person : NSObject
#property float heightInMeters;
#property int weightInKilos;
#end
The code still inherits and executes just fine.
1. What is the point of even declaring them there in the first place if we can just create two properties?
2. why create two instance variables AND properties to correspond with them?
3. I know that we can declare the variables in the .m instead to keep them private to the class and everything that subclasses it. like this:
#implementation Person {
float heightInMeters;
int weightInKilos;
}
What is the difference here? I feel like I'm missing a lot of basics. Is there a simplistic way of putting this all in perspective?
When you declare a #property, the compiler will automatically synthesize the variable prefixed with an underscore, a getter method, and a setter method.
#interface MyClass ()
#property(strong, nonatomic) NSString *myString;
#end
In this example the compiler would syhtnesize the variable as _myString, the getter as
-(NSString *)myString
and the setter as
-(void)setMyString:(NSString *)string
The keywords after "#property" (strong, nonatomic) define the property's attributes. strong, the default, implies ownership, meaning that in this case MyClass instances will essentially be responsible for the retain/release of their respective myString objects. nonatomic means the variable is not guaranteed to always be a valid value in a multithreaded environment, for example if the getter is called at the same time as the setter.
Additionally, the compiler will treat dot syntax used to retrieve/set instance variables as calls to the appropriate getter/setter methods. Therefore, given an instance of MyClass
MyClass *exampleClass = [[MyClass alloc] init];
Both of the following are equivalent statements:
NSString *string1 = example.myString; // dot syntax
NSString *string1 = [example myString]; // explicit call to the getter method
For further reading, take a look at Apple's Programming with Objective-C Guide.
As for your specific questions:
1. What is the point of even declaring them there in the first place if we can just create two properties?
It's actually not a good idea to declare variables explicitly as public variables in your MyClass.h file (or in most other cases). Instead, declaring them as properties automatically creates a private variable (and accessor methods), making adhering to OOP best practices a little easier. So there is no point in declaring
// MyClass.h
#interface MyClass : NSObject {
NSString *myString // public variables not good
}
Also because of what I stated above regarding dot syntax, if you use self.myString internally in MyClass.m or instanceOfMyClass.myString externally, the public variable myString will never even be touched because the synthesized variable is named _myString.
2. Why create two instance variables AND properties to correspond with them?
See above--you don't need two instance variables, only one.
3. I know that we can declare the variables in the .m instead to keep them private to the class and everything that subclasses it. What is the difference here? I feel like I'm missing a lot of basics. Is there a simplistic way of putting this all in perspective?
If you declare your variables privately in the #implementation part of your .m file, the compiler won't be able to help you by synthesizing the getters and setters. Even as private methods, getters and setters can help reduce complexity in your code, for example checking for the validity of variable values. (Note: you can override accessor methods.)
// MyClass.m
#interface MyClass () // private interface
#property(nonatomic, strong) NSString *myString;
#end
#implementation MyClass {
// no more need for private variables!
// compiler will synthesize NSString *_myString and accessors
}
-(void)setMyString:(NSString *)string { // overwrite setter
// no empty strings allowed in our object (for the sake of example)
NSAssert([string length] > 0, #"String must not be empty");
// assign private instance variable in setter
_myString = string;
}
#end
This way, even when you subclass MyClass, the subclass will inherit the getter and setter methods that were synthesized for us by the compiler.

Is dot syntax or bracket syntax correct for property access?

Suppose I have
#interface A : NSObject
#property (nonatomic, strong) NSMutableArray *array;
#end
Later on in another class B, I want to access that array, to check how many items are in it. I can do one of two things in B (a is an instance of A):
Option 1
[a.array count]
Option 2
[[a array] count];
Which option is the best way to do this? Is option 2 the right way to access the array when using [a array] as the getter method?
both are the same if you have synthesized the array. in first one you just call the property and in 2nd one you are calling the getter method which was generated by #synthesize action.
and sure the 2nd option is the right way as #synthesize makes two methods
1- getter that is same as the property name
2- setter that is add set with property name at start with first letter captial like setArray.
There is no difference between the two if you have synthesized the array, as The Saad said. However, I recommend bracket syntax as to remain consistent in all your method calling as all other Objective-C methods (aside from functions from C) use bracket syntax to be called.
There's no difference until you decide to rename the generated getter/setter methods and the message is likely to become invalid.
For the public instance variables you can skip the accessor methods (both property and method styles) and use the structure dereference operator:
#interface A : NSObject
{
NSMutableArray *array;
}
#property (nonatomic, strong) NSMutableArray *array;
#end
classA.m
[self->array count];
classB.m
[a->array count];
Doing this, you waive the convenience of both operation and memory management optimizations which you have using properties (in both access styles) with the different attributes, see more.
As example for the NSString property
#property (readwrite, copy) NSString *sVar;
the generated setter looks like this:
-(void)setSVar:(NSString*)inSVar
{
if (self->sVar != inSVar)
{
[self->sVar release];
self->sVar = [inSVar copy];
}
}

Features of use #property and #synthesize (cocos2d)

I saw in the libraries for use cocos2d strange #property and #synthesize
Standard in the examples is written as follows:
in .h
CGFloat minimumTouchLengthToSlide;
}
#property(readwrite, assign) CGFloat minimumTouchLengthToSlide;
in .m
#synthesize minimumTouchLengthToSlide
But in lib https://github.com/cocos2d/cocos2d-iphone-extensions/tree/master/Extensions/CCScrollLayer and another libs\extensions
in .h
CGFloat minimumTouchLengthToSlide_;
}
#property(readwrite, assign) CGFloat minimumTouchLengthToSlide;
in .m
#synthesize minimumTouchLengthToSlide = minimumTouchLengthToSlide_;
What is the meaning of this code?
Why they changed minimumTouchLengthToSlide to minimumTouchLengthToSlide_ and added minimumTouchLengthToSlide = minimumTouchLengthToSlide_;
Its often considered good practice to name the instance variable different from the property. The resoning behind this is that in that case you cannot accidently use the instance variable instead of the property. This is not that important when using value types such as integers and floats but more important when using reference types on retain properties. Consider a property
#property (nonatomic, retain) NSString *myString;
...
#synthesize myString;
The compiler takes care of retaining the string when you do self.myString = someString. But when you write myString = someString you do not actually use the property but rather the variable directly and no retaining will take place. This can lead to zombies, leaks etc. By giving the instance variable a different name like this:
#property (nonatomic, retain) NSString *myString;
...
#synthesize myString = myString_;
you can no longer write myString = someString because this would issue a compiler error. If you needed to use the instance variable directly you could always write _myString = someString but in practice this is rarely needed.
There are other cases when you write explicit property methods but the issue is basically the same, you cannot accidently bypass the property methods when using the second variant.
So basically this is a method to avoid unnecessary errors when handling properties (mostly retain-properties).
#property and #synthesize are a really cool feature of Objective-C to allow the automatic creation of getter and setter methods. In your examples they would create:
- (CGFloat)minimumTouchLengthToSlide and
- (void)setMinimumTouchLengthToSlide:(CGFloat)newLength; for free.
#synthesize minimumTouchLengthToSlide = minimumTouchLengthToSlide_ means they are telling Objective-C that when someone tries to access that property, then it should point at the instance variable minimumTouchLengthToSlide_
readwrite,assign describe what happens when someone sets the property. Assign means that the value is not retained, the variable is just pointed. An example of what that method might look like could be this:
- (void)setMinimumLengthToSlide:(CGFloat)newLength {
[self willChangeValueForKey:#"minimumLengthToSlide"]; // let observers know this property is changing
minimumLengthToSlide_ = newLength;
[self didChangeValueForKey:#"minimumLenghtToSlide"];
}
You can read more about them here.

Do I need to declare a property in the instance variables section, too? What do I gain?

I read some tutorials here about properties ,but i still have some doubts to clarify, is there a difference between
#interface MyClass : NSObject {
}
#property(nonatomic,retain) NSString *temp;
#end
AND
#interface MyClass : NSObject {
NSString *temp;
}
#property(nonatomic,retain) NSString *temp;
#end
The difference is that in the first version, the compiler will automatically create an instance variable (IIRC, it will be named _temp but I don't know for sure). This is only supported on iOS and Mac 64 bit.
In the second example, you provide the variable.
There's actually a way to tell the compiler which variable to use for the property, which I use a lot:
#interface MyClass : NSObject {
NSString *temp_;
}
#property(nonatomic,retain) NSString *temp;
#end
#implementation MyClass
#synthesize temp = temp_;
#end
This way the variable and the property have different names and you can't confuse them (e.g. by forgetting to prefix self.).
Minor side-note: it's often desirable to use copy instead of retain for NSString *, since you might assign an NSMutableString * to the property. Now if you would change that mutable string unexpected things might happen.
Does the first one even work? If there is no instance variable its a bit hard to have a property to access it.
#properties are meant for you, so you can be lazy, they write the following 2 methods for you ( if not set to readonly ):
- (void)setYourVariable:(id)new;
- (id)yourVariable;
it also allows you to use "someClass.itsVariable;" instead of "[someClass itsVariable];"
Another thing, when you create your header files make sure that the biggest variables ( like pointers ) are on the top and the smallest on the bottom, this saves ram.
thus:
NSObject *someObject;
NSObject *someOtherObject;
int anInt;
short aShort;
BOOL fakeBool;
instead of:
BOOL fakeBool;
NSObject *someObject;
short aShort;
NSObject *someOtherObject;
int anInt;
This has to do with the compiler, you can check this by using sizeof()
In the modern runtime (Objective-C 2.0) it is the same because the compiler will generate the variable for you. See Question about #synthesize
Quoting The Objective-C Programming Language > Declared Properties > Property Implementation Directives:
There are differences in the behavior of accessor synthesis that
depend on the runtime:
For the legacy runtimes, instance variables must already be declared in the #interface block of the current class. If an instance
variable of the same name as the property exists, and if its type is
compatible with the property’s type, it is used—otherwise, you get a
compiler error.
For the modern runtimes, instance variables are synthesized as needed. If an instance variable of the same name already exists, it is
used.
The practical difference that I've found is that the debugger doesn't appear to show you the value of properties, just instance variables.
Therefore, your first example, which (assuming you use the #synthesize directive to create your getter/setter) automatically creates the ivar, will not have a value that you can easily retrieve during debug. You'll end up having to send a lot of NSLog messages, rather than just looking at the values while stepping through your code.
As an aside, which seems to relate to this topic, I typically prepend my ivars with "iv" and change my color settings in XCode preferences so that I'm never unsure whether I'm accessing a property or an ivar.
Example
#interface MyClass : NSObject {
NSString *ivName;
NSString *ivTitle;
}
#property (nonatomic, copy) NSString *Name;
#property (nonatomic, copy) NSString *Title;
#end
Now, this then requires a small trick (to tie the two together) when synthesizing the properties, which I show below:
#implementation MyClass
#synthesize Name = ivName;
#synthesize Title = ivTitle;
This way, it's always very easy for me to know exactly what's going on at a glance. Yes, context can also tell you whether you're accessing an ivar/property, but why not make it easier?

Basic Objective C defining and synthesizing properties

I have been working with Objective C for a few months now and feel like I maybe know 1% of it, and understand even less than that...
Regardless, I have two moderately popular games out, and learning more every day.
When I first started, I learned that the method of defining properties was to use the same identifier for the property and the instance variable, as follow:
code.h:
#interface MyClass : UISomething {
NSString *myPropName;
}
#property (nonatomic, retain) NSString *myPropName;
#end
code.m
#synthesize myPropName;
Recently I saw the following used, where the instance variable is named differently than the property, and then the property is set to the instance variable in the implementation:
code.h:
#interface MyClass : UISomething {
NSString *_myPropName;
}
#property (nonatomic, retain) NSString *myPropName;
#end
code.m:
#synthesize myPropName = _myPropName;
Is there a reason for not using same identifier for the property and instance variable?
Thanks!
Hanaan
Is there a reason for not using same
identifier for the property and
instance variable?
Not really. Some people like the convention of prefixing the instance variables with an underscore. (Seems pointless to me.) Other people like to change the property names for boolean variables:
#synthesize isEmpty = empty;
You might also want to use a shorter identifier for the instance variable and more descriptive name for the property (audioPlayer = player). And one final application comes to mind, renaming variables in combination with protocols:
#interface LowLevelAudioPlayer : NSObject <AudioLevelProvider> {…}
#interface Jukebox : NSObject {
LowLevelAudioPlayer *player;
}
#property(readonly) id <AudioLevelProvider> levelMeter;
#synthesize levelMeter = player;
Here it’s beneficial to rename the variable as you are only providing access to one of its facets.