0

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
Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
Rajashekar
  • 619
  • 9
  • 30
  • sorry i tried and was not able to put the code in the correct format. i tried to put it in {} still did not work. i dont know how. any tips on this? – Rajashekar Jul 14 '11 at 09:56
  • You don't have to put code in {}. Instead you paste your code, select it and click on {}, which is a button just above the text field. – Codo Jul 14 '11 at 10:07
  • @codo thanks, now i got it. sorry i was trying to do it like the cocos2d forum. – Rajashekar Jul 14 '11 at 10:39
  • @Rajashekar FYI, if you put the "objective-c" tag in your post it will syntax highlight / color code your post for the objective-c language. – ipatch Dec 15 '13 at 21:54

4 Answers4

0

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()

Antwan van Houdt
  • 6,989
  • 1
  • 29
  • 52
  • Yes, the first one does work on iOS and Mac 64 bit, but not on Mac 32 bit. The compiler generates an instance variable for you. BTW, I don't believe your remark about saving space is true, can you back that up with some link ? Because the compiler should align the variables in a CPU convenient way and reordering wouldn't change the amount of space used. – DarkDust Jul 14 '11 at 10:13
  • @DarkDust try it, and find it, it is true. use sizeof() – Antwan van Houdt Jul 14 '11 at 10:18
  • 1
    @DarkDust when I have 2 NSStrings no top, 2 booleans on the bottom it has a size of 32, when I do them in a random order, bool pointer pointer bool it is 40 – Antwan van Houdt Jul 14 '11 at 10:21
  • @Antwan van Houdt , yes it does work and i was not sure in which cases it was working(like on iOS and Mac 64 bit, but not on Mac 32 bit). – Rajashekar Jul 14 '11 at 10:43
  • @Antwan van Houdt: Very interesting, thanks for letting me know. – DarkDust Jul 14 '11 at 10:51
0

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.

DarkDust
  • 90,870
  • 19
  • 190
  • 224
0

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.

Community
  • 1
  • 1
Jano
  • 62,815
  • 21
  • 164
  • 192
0

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?

mbm29414
  • 11,558
  • 6
  • 56
  • 87