Accessing a property from a C method in Cocoa - objective-c

I'm trying to learn Objective C & Cocoa, but I just can't manage to access a property inside an Object. Specifically an object from a C method. I'm working with the chipmunk dynamics library.
Chipmunk has something similar to NSPoint called cpVect. Now I have no problem defining a cpVect inside my object, but when I try to make the accessors using #property & #synthesize I keep getting errors: so
#interface ControlsLayer : Layer {
Sprite * touchMarker, *dragMarker;
cpVect * forceVector;
}
works fine
but
#interface ControlsLayer : Layer {
Sprite * touchMarker, *dragMarker;
cpVect * forceVector;
}
#property (retain) cpVect forceVector;
#end
gives me the error "property 'forceVector' with 'retain' must be of object type"
so without 'retain' i get an different error
"type of property 'forceVector' does not match type of ivar 'forceVector'"
I'm going round in circles trying to figure this out, is there a particular type I can use, is it an incompatibility between chipmunk and cocoa, or... or.... I don't know. Chipmunk is very light on the documentation and all the examples I've found don't seem to use objects, all the examples just use one class to process everything.
Any help, greatly appreciated. This thing is driving me nuts.

The error your are getting is because the semantics of retain (ie. reference counted memory management, with the setter incrementing the ref count on the new value and decrementing the ref count of the old value) only make sense for Objective-C objects. The default semantics for properties are retain, but you can specify that the property be assign like so:
#property (assign) cpVect *forceVector;
where I assume that the property is actually a cpVect*, not a cpVect as you've written.

You've got a pointer to a cpVect in your instance Variable but not in your property.
Try this:
#property (assign) cpVect * forceVector;

Related

Getter and Setter Explained?

I am just learning OOP from a book I picked up (Big Nerd Ranch), and it just went through the getter and setter chapter. I would just like to clarify I understand what I have just done. Instead of creating a method to set the value of an instance, and then another method to extract the value and display it, I create use the #property and #synthesize syntax to define both methods.
Instead of doing this:
-(void) setHeightOfObject:(int)h;
-(void) setWeightOfObject:(float)w;
-(int) heightOfObject;
-(float) weightOfObject;
and defining it like this:
- (int)heightOfObject
{
return heightOfObject;
}
- (void)setHeightOfObject:(int)h
{
heightInMeters = h;
}
- (float)weightOfObject
{
return weightOfObject;
}
- (void)setWeightOfObject:(float)w
{
weightOfObject = w;
}
I would do this with getter and setters in the .h file:
#property int heightOfObject;
#property float weightOfObject;
And then go to my .m file and link it:
#synthesize heightInMeters, weightOfObject;
This then gives me the ability to set the value of my object, and then get it if I need it printed? I know this is an important concept and I want to make sure I have the proper grasp of it.
You are correct. The #synthesize essential expands out to the implementation you wrote while compiling.
Since writing getters and setters is boring and repetitive (and most objects have a bunch of properties you'd want getters and setters for) having this little shortcut makes you spend less time on boilerplate code and more time implementing something interesting.
If you'd like more detailed information about objective-c's properties, you can have a look at the programming guide (although this might be somewhat unnecessarily detailed for you at this point).
There are two parts to what you are achieving by using #property and #synthesize.
#property tells the compiler that it should allow you to use dot syntax to call the accessors of heightOfObject and weightOfObject. So doing this
int height = myObject.heightOfObject;
myObject.weightOfObject = 10;
becomes legal code and is exactly equivalent to this:
int height = [myObject heightOfObject];
[myObject setWeightOfObject:10];
You can use #property without #synthesize, in which case you must implement the accessors exactly as you have done in your question.
Using #synthesize tells the compiler that it should generate the accessors for you and it will also generate the instance variables themselves if your runtime supports it (e.g. on iOS and 64-bit OS X).
Property and synthesise were introduced in Objective C 2.0 in order to provide a straightforward way to create getters and setters.
Check this link it will be of help:
http://cocoacast.com/?q=node/103
You not only get getters and setters. You also get a neat syntax: self.heightOfObject which you can assign to or read from.
#property has a lot of settings though so you might want to read in detail. In particular you can control whether you need both read and write access or only one of them.

XCode 4 c array of objective-c objects

With XCode 3 compiler, I could manage an array of objects like:
#interface myView:UIView
{
CALayer *layer[4];
}
#property (nonatomic,retain) CALayer **layer;
#end
#implementation myView
#dynamic layer;
- (CALayer **)layer { return layer; }
// I could then access elements like
- (void) example
{
self.layer[3] = NULL;
}
#end
With XCode 4 compiler the #property declaration generates an error "Property with retain must be an object type".
I guess best way to fix is to convert to NSArray, but I have 100's lines of code using the c-style array subscript (e.g., self.layer[i]). Is there some other way to fix?
Several problems with this code:
It should be MyView, not myView; classes start with capital letters.
CALayer ** is not an object type; it is a pointer to an object type, hence the compiler complaint. Simply making it assign will make it compile, but it'll still be wrong.
There is likely no reason to use a language array (MyClass foo[4]) to hold this data. Use an NSMutableArray (you can use [NSNull null] as a stand-in for "this slot is not populated".
If you really want to stick with the language array, drop the retain. Just remember that you have to explicitly manage the retain/releases of the objects within the array. The #property won't do that for you.
Also, while it may seem a pain to fix your code to be inline with typical standard patterns, it is only going to be more costly to do so as the code evolves and, someday, you'll likely be in a situation where you really need to do so....
Change it to an assign property so you don't try to retain a non-object?
You cannot use Objective-C memory management calls (i.e. retain) on a C array. You need to manage your array using standard C or C++ logic. You need to malloc and free memory on your own. If you do not need to retain the array then you can remove the retain property.

Property - Implementation of variables in Objective-C

Well ! I got confused about the way of declaring variables & implementing its properties.
The .h File contents
#interface XYZAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet XYZViewController *viewController;
#end
The .m File Contents
#import "XYZAppDelegate.h"
#import "XYZViewController.h"
#implementation XYZAppDelegate
#synthesize window=_window;
#synthesize viewController=_viewController;
My questions/Queries are as follows.
Don't we require to declare variables if we put property ? ( Using property, we can indirectly declare variable - is it like that ? )
What are the additional features other than this ? ( In coding specific )
Why does everybody insist to use _ before each property accessor ? ( Other than security threats ? Has it become coding standard ? Whats the reason behind it? )
You do not have to declare the
variable. It is done automatically,
I believe by #synthesize. One
advantage to declaring it is that the
debugger will automatically list it.
Weigh this against the ugliness of
redundant definition.
Other features: read only properties,
assigned (unretained) values.
The underscore is a convention for
naming member variables that are
differently named than properties and
method variables. Apple's samples
sometimes use this convention and
sometimes do not. I view it as
usually unnecessarily verbose as a
programmer can easily tell the
difference between myVariable and
self.myVariable.
1) Don't we require to declare variables if we put property ? ( Using property, we can indirectly declare variable - is it like that ? )
No. You aren't required to declare variables for the corresponding properties. You are required to use the #synthesize propertyName command which tells the compiler to create those variables for you.
2) Why does everybody insist to use _ before each property accessor ? ( Other than security threats ? Has it become coding standard ? Whats the reason behind it? )
Most people (all?) have been stung by memory management nightmares. Some of these are caused by sloppy/lazy/zero-sleep coding. Using #synthesize propertyName = _propertyName allows the programmer to immediately know that the underscored variable is private to the class, and is unretained. It prevents issues where you specifically allocate or copy an object to store in the property, or accidentally assign an autoreleased object to the ivar.
Consider:
1) An autoreleased object being assigned to an unretained ivar.
#synthesize propertyName;
propertyName = [NSString stringWithFormat:#"I've just made %#", "a boo-boo."];
"propertyName" now references an object that will soon not exist, which will create EXEC_BAD_ACCESS errors down the road (as soon as it's referenced again).
2) A retained object being set to the retained property.
#synthesize propertyName;
self.propertyName = [[NSString alloc] initWithFormat:#"I just created %#", #"a leak"]
Now we've created an NSString object, and set it to the propertyName property, which itself is retaining the variable. Now the object is double retained and won't be properly released.
Both of these issues are easy to combat (even when tired, albeit less so) when you properly name your ivars with an underscore. It's not a fool-proof method, but it makes it considerably easier to manage the retain counts of objects in your head.
(1) No, not with the new 64-bit only features. The variables are declared for you, automatically.
(2) I don't know what you're asking here.
(3) It's just a convention, so that the variable name is different from the accessor name. Makes it clearer which you're dealing with.

Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects

I'm currently using the iOS 5 SDK trying to develop my app.
I'm trying to make an NSString a property, and then to synthesize it in the .m file (I have done this before with no issues). Now, I came across this: "Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects."
This is my code:
.h
#interface ViewController : UIViewController {
NSString *newTitle;
}
#property (strong, nonatomic) NSString *newTitle;
.m
#synthesize newTitle;
Does anyone have a clue how I could fix this?
Thanks!!
My guess is that the compiler version you’re using follows the memory management rules for declared properties, too — more specifically, for declared properties’ accessors:
You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy”.
A property named newTitle, when synthesised, yields a method called -newTitle, hence the warning/error. -newTitle is supposed to be a getter method for the newTitle property, however naming conventions state that a method whose name begins with new returns an object that’s owned by the caller, which is not the case of getter methods.
You can solve this by:
Renaming that property:
#property (strong, nonatomic) NSString *theNewTitle;
Keeping the property name and specifying a getter name that doesn’t begin with one of the special method name prefixes:
#property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
Keeping both the property name and the getter name, and telling the compiler that, even though the getter name starts with new, it belongs to the none method family as opposed to the new method family:
#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non-clang compilers
#endif
#if __has_attribute(objc_method_family)
#define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
#else
#define BV_OBJC_METHOD_FAMILY_NONE
#endif
#interface ViewController : UIViewController
#property (strong, nonatomic) NSString *newTitle;
- (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
#end
Note that even though this solution allows you to keep newTitle as both the property name and the getter name, having a method called -newTitle that doesn’t return an object owned by the caller can be confusing for other people reading your code.
For the record, Apple have published Transitioning to ARC Release Notes, in which they state:
You cannot give a property a name that begins with new or copy.
They’ve already been notified that their statement is not quite accurate: the culprit is the getter method name, not the property name.
Edit 17 Jan 2015: I’ve just noticed a recent commit to Clang that suggests option 3 above (using objc_method_family(none)), including a fix-it, for the general case where a property name matches one of the special method family prefixes. Xcode will likely incorporate this change eventually.
Unacceptable Object Names
newButton
copyLabel
allocTitle
Acceptable Object Names
neueButton
mCopyLabel
_allocTitle
#arc #auto-synthesized #xcode-4.6.1
** EDIT **
Apparently you can't use mutableCopy either.
The name of the member starting with new is what triggers the warning. Change the name to editedTitle and the warning will go away. I was unable to find documentation confirming this but through testing was able to determine that member variables that begin with 'new' aggravate the compiler.
ARC does not allow to use "New...." in property name. but you can use "newTitle" by changing getter name.
#property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
It doesn't look like what Bavarious was suggesting was what you wanted to do. All you want to do is declare an instance variable NewTitle and then synthesize the property. We used to have to declare the instance variable and property. No more.
Now, I believe the right way of doing this is the following:
.h
#interface ViewController : UIViewController
#property (nonatomic, strong) NSString *newTitle;
.m
#synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
The instance variable for the property newTitle is synthesized. You don't want your instance variable to be the same as your property - too easy to make mistakes.
See Example: Declaring Properties and Synthesizing Accessors
In CoreData if you use "new..." in attribute (compile normally) it will crash randomly with a "bad access" exception.
There is no crash log and the line shown with the "All Exceptions Breakpoint" will not help you at all.
Writing a setter manually with the name same as the property's removed this warning.
NS_RETURNS_NOT_RETAINED is used to solve the naming problem.
#property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;
We can find its definition as follows:
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
The 'ns_returns_not_retained' attribute is the complement of 'ns_returns_retained'. Where a function or method may appear to obey the Cocoa conventions and return a retained Cocoa object, this attribute can be used to indicate that the object reference returned should not be considered as an "owning" reference being returned to the caller. The Foundation framework defines a macro NS_RETURNS_NOT_RETAINED that is functionally equivalent to the one shown below.
Besides the issue that you should/can't use "new" in front of you property names, let say one more thing: Try to avoid "new" in front of names in general. "New" is dependent on time. Currently it is new for you, but some time later you maybe want to implement something new again. So using "new" in names is always bad. Try to think this way: In the programming world, "new" is always creating something: a new instance of something.
In your case when you want to assign a different title then the current name your property titleReplacement.
One more thing: Try to name functions and methods with the verb first, like setSomething or getSomething.
But in properties try to name the object first, like heightMinimum, heightMaximum, etc. -> when you use your inspector when you are coding, you always looking for objects. Try it out. ;-)
try this:-
#property (nonatomic,retain) NSString *newTitle;

Where are the synthesized ivars stored?

I've been reading up on the automatically synthesized ivars. My question is, "WHere are automatically they allocated?" I would have expected them to be part of self, so that I could see them in the debugger, but it seems that the only way I can see them is by invoking the accessor method (via the gdb 'po' command). Isn't there space in the class/object's struct (as there would be for an explicitly declared ivar)?
(Is there a description of the in-memory representation for a modern Objective-C object?)
Being a C guy, it makes me very uncomfortable to not to be able to see where everything is. :-P
Looks like this will tell you:
How do automatic #synthesized ivars affect the *real* sizeof(MyClass)?
I am a C guy at heart too. Why bother using these auto generated ones? I like looking at a class and seeing what it holds onto in terms of data.
Interesting: Neat how they took the 64 bit change to make things better.
http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html
They are added to the objective-c object (which is a C structure) no different to a regular ivar, so for example:
#interface TestObject : NSObject {
}
#property (nonatomic, assign) int theInt;
#end
#implementation QuartzTestView
#synthesize theInt;
#end
You can refer to theInt ivar directly (not through property accessors) either:
- (void)someMethod {
theInt = 5;
}
OR
- (void)someOtherMethod {
self->theInt = 10;
}
See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html - using the modern runtime an instance variable "will be synthesized for you". It can be nice to add a variable yourself instead though (so that you can see it when debugging in self), however you have to be careful not to do direct assignments to the instance variable for retain or copy based properties.