Is there a way to do lazy initialization of a atomic property without having to write setter and getter by hand? - iphone

Apparently it's not possible to use #synthesize when overwriting an atomic property accessor. Xcode 4 will produce a warning.
Now, is there another way of using lazy initialization of atomic properties while still letting Xcode synthesize both getter and setter automatically, without overwriting any of them?

What you need to do is write both the setter and the getter. You can still #synthesize to get the storage. e.g.:
//.h
#property (strong) id x;
//.m
#synthesize x = _x;
- (id)x
{
#synchronized(self)
{
if (!_x)
{
_x = [[MyX alloc] init];
}
return _x;
}
}
- (void)setX:(id)x
{
#synchronized(self)
{
_x = x;
}
}
You may need to do additional memory management without ARC and may want to create a different lock (instead of self) or use a different synchronisation method, but it'll give you the gist.

Related

Use of undeclared identifier

I'm trying to use this project which is a synthesizer for Objective-C for an iPhone application I'm building. However, I'm having trouble with the MHAudioBufferPlayer class.
In the MHAudioBufferPlayer.m class, I'm getting a bunch of Use of undeclared identifier errors for _gain, _playing, and _audioFormat. This makes sense, as those identifiers are never declared with an underscore in front of them. However, they are declared in the MHAudioBufferPlayer.h class without the underscores.
I'm sort of confused by this as I'm new to Objective-C. Does an underscore denote a special action to be taken? Is it supposed to be translated into self.gain, self.playing, etc.? How can I fix this? Or is this code just buggy?
- (id)initWithSampleRate:(Float64)sampleRate channels:(UInt32)channels bitsPerChannel:(UInt32)bitsPerChannel packetsPerBuffer:(UInt32)packetsPerBuffer
{
if ((self = [super init]))
{
_playing = NO;
_playQueue = NULL;
_gain = 1.0;
_audioFormat.mFormatID = kAudioFormatLinearPCM;
_audioFormat.mSampleRate = sampleRate;
_audioFormat.mChannelsPerFrame = channels;
_audioFormat.mBitsPerChannel = bitsPerChannel;
_audioFormat.mFramesPerPacket = 1; // uncompressed audio
_audioFormat.mBytesPerFrame = _audioFormat.mChannelsPerFrame * _audioFormat.mBitsPerChannel/8;
_audioFormat.mBytesPerPacket = _audioFormat.mBytesPerFrame * _audioFormat.mFramesPerPacket;
_audioFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
_packetsPerBuffer = packetsPerBuffer;
_bytesPerBuffer = _packetsPerBuffer * _audioFormat.mBytesPerPacket;
[self setUpAudio];
}
return self;
}
If you are using new compiler that comes with Xcode4.4 onwards, then for each of your property it creates an automatic synthesize with _(underscore) as prefix.
Like, if you have created #property.... playing;
then the compiler creates #synthesize playing=_playing;
If you are in older versions of Xcode, this need to be done manually.
#synthesize generated by Xcode => 4.4 as the default. The generated private instance variable, ivar, created for you by Xcode has a leading underscore '' if you don't explicitly create your own #synthesize statement. You MUST include the leading '' when sending messages to this
property (typically UI element as an outlet from your controller.m file).
That is
#property textField;
[_textField setStringValue: #"foo"]; if you DON'T write the '#synthesize'.
The compiler's done this for you, and has made a private instance variable by synthesizing the getter/setters. The convention is to make the private ivar the name of the property prepended by the leading underscore.
OR
#synthesize textField;
#property textField;
[textField setStringValue: #"foo"]; if you DO write your own '#synthesize' or are < Xcode 4.4.
Here, the complier has NOT done it for you, your ivar name/property name are the same and can be used w/o the leading '_'.
Good luck.
Depending on what version of XCode you are using, and compiler there are different ways of doing it. I don't know how familiar you are with OOP, if you are not I suggest you read up a bit on setters and getters and objects as it is the basis of almost everything you will do from now on.
Some examples, Old school style, will create an ivar. In your .h:
#interface TheViewController : UIViewController{
NSString *theString;
}
A bit new style, will create setter and getter In your .h.
#interface TheViewController : UIViewController
#property (nonatomic, weak) NSString *theString;
In your .m file:
#implementation TheViewController
#synthesize theString = _theString;
Can be accessed by _theString or self.theString
The new way of doing it. In your .h file:
#property (nonatomic, weak) NSString *theString;
The compiler Will create everything the above way did.
Hope that helps you a bit.

Declaration/definition of variables locations in ObjectiveC?

Ever since starting to work on iOS apps and objective C I've been really puzzled by the different locations where one could be declaring and defining variables. On one hand we have the traditional C approach, on the other we have the new ObjectiveC directives that add OO on top of that. Could you folks helps me understand the best practice and situations where I'd want to use these locations for my variables and perhaps correct my present understanding?
Here's a sample class (.h and .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
#end
and
#import "SampleClass.h"
// 4) what goes here?
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
#implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
#end
My understanding of 1 and 4 is that those are C-style file-based declarations and definitions that have no understanding whatsoever of the concept of class, and thus have to be used exactly how they would be used in C. I've seen them used for implementing static variable-based singletons before. Are there other convenient uses I'm missing?
My take from working with iOS is that ivars have been alost completely phased out outside of the #synthesize directive and thus can be mostly ignored. Is that the case?
Regarding 5: why would I ever want to declare methods in private interfaces? My private class methods seem to compile just fine without a declaration in the interface. Is it mostly for readability?
Thanks a bunch, folks!
I can understand your confusion. Especially since recent updates to Xcode and the new LLVM compiler changed the way ivars and properties can be declared.
Before "modern" Objective-C (in "old" Obj-C 2.0) you didn't have a lot of choices. Instance variables used to be declared in the header between the curly brackets { }:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#end
You were able to access these variables only in your implementation, but not from other classes. To do that, you had to declare accessor methods, that look something like this:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
- (int)myVar;
- (void)setMyVar:(int)newVar;
#end
// MyClass.m
#implementation MyClass
- (int)myVar {
return myVar;
}
- (void)setMyVar:(int)newVar {
if (newVar != myVar) {
myVar = newVar;
}
}
#end
This way you were able to get and set this instance variable from other classes too, using the usual square bracket syntax to send messages (call methods):
// OtherClass.m
int v = [myClass myVar]; // assuming myClass is an object of type MyClass.
[myClass setMyVar:v+1];
Because manually declaring and implementing every accessor method was quite annoying, #property and #synthesize were introduced to automatically generate the accessor methods:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#synthesize myVar;
#end
The result is much clearer and shorter code. The accessor methods will be implemented for you and you can still use the bracket syntax as before. But in addition, you can also use the dot syntax to access properties:
// OtherClass.m
int v = myClass.myVar; // assuming myClass is an object of type MyClass.
myClass.myVar = v+1;
Since Xcode 4.4 you don't have to declare an instance variable yourself anymore and you can skip #synthesize too. If you don't declare an ivar, the compiler will add it for you and it will also generate the accessor methods without you having to use #synthesize.
The default name for the automatically generated ivar is the name or your property starting with an underscore. You can change the generated ivar's name by using #synthesize myVar = iVarName;
// MyClass.h
#interface MyClass : NSObject
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#end
This will work exactly as the code above. For compatibility reasons you can still declare ivars in the header. But because the only reason why you would want to do that (and not declare a property) is to create a private variable, you can now do that in the implementation file as well and this is the preferred way.
An #interface block in the implementation file is actually an Extension and can be used to forward declare methods (not needed anymore) and to (re)declare properties. You could for instance declare a readonly property in your header.
#property (nonatomic, readonly) myReadOnlyVar;
and redeclare it in your implementation file as readwrite to be able to set it using the property syntax and not only via direct access to the ivar.
As for declaring variables completely outside of any #interface or #implementation block, yes those are plain C variables and work exactly the same.
First, read #DrummerB's answer. It a good overview of the whys and what you should generally do. With that in mind, to your specific questions:
#import <Foundation/Foundation.h>
// 1) What do I declare here?
No actual variable definitions go here (it's technically legal to do so if you know exactly what you're doing, but never do this). You may define several other kinds of things:
typdefs
enums
externs
Externs look like variable declarations, but they're just a promise to actually declare it somewhere else. In ObjC, they should only be used to declare constants, and generally only string constants. For instance:
extern NSString * const MYSomethingHappenedNotification;
You would then in your .m file declare the actual constant:
NSString * const MYSomethingHappenedNotification = #"MYSomethingHappenedNotification";
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
As noted by DrummerB, this is legacy. Don't put anything here.
// 3) class-specific method / property declarations
#end
Yep.
#import "SampleClass.h"
// 4) what goes here?
External constants, as described above. Also file static variables can go here. These are the equivalent of class variables in other languages.
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
Yep
#implementation SampleClass
{
// 6) define ivars
}
But very rarely. Almost always you should allow clang (Xcode) to create the variables for you. The exceptions are usually around non-ObjC ivars (like Core Foundation objects, and especially C++ objects if this is an ObjC++ class), or ivars that have weird storage semantics (like ivars that don't match with a property for some reason).
// 7) define methods and synthesize properties from both public and private
// interfaces
Generally you shouldn't #synthesize anymore. Clang (Xcode) will do it for you, and you should let it.
Over the last few years, things have gotten dramatically simpler. The side-effect is that there are now three different eras (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). So when you see the older code, it can be a little confusing. Thus confusion arising from simplicity :D
I'm also pretty new, so hopefully I don't screw anything up.
1 & 4: C-style global variables: they have file wide scope. The difference between the two is that, since they're file wide, the first will be available to anyone importing the header while the second is not.
2: instance variables. Most instance variables are synthesized and retrieved/set through accessors using properties because it makes memory management nice and simple, as well as gives you easy-to-understand dot notation.
6: Implementation ivars are somewhat new. It's a good place to put private ivars, since you want to only expose what's needed in the public header, but subclasses don't inherit them AFAIK.
3 & 7: Public method and property declarations, then implementations.
5: Private interface. I always use private interfaces whenever I can to keep things clean and create a kind of black box effect. If they don't need to know about it, put it there. I also do it for readability, don't know if there are any other reasons.
This is an example of all kinds of variables declared in Objective-C. The variable name indicate its access.
File: Animal.h
#interface Animal : NSObject
{
NSObject *iProtected;
#package
NSObject *iPackage;
#private
NSObject *iPrivate;
#protected
NSObject *iProtected2; // default access. Only visible to subclasses.
#public
NSObject *iPublic;
}
#property (nonatomic,strong) NSObject *iPublic2;
#end
File: Animal.m
#import "Animal.h"
// Same behaviour for categories (x) than for class extensions ().
#interface Animal(){
#public
NSString *iNotVisible;
}
#property (nonatomic,strong) NSObject *iNotVisible2;
#end
#implementation Animal {
#public
NSString *iNotVisible3;
}
-(id) init {
self = [super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
iPrivate = #"iPrivate";
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
_iPublic2 = #"iPublic2";
iNotVisible = #"iNotVisible";
_iNotVisible2 = #"iNotVisible2";
iNotVisible3 = #"iNotVisible3";
}
return self;
}
#end
Note that the iNotVisible variables are not visible from any other class. This is a visibility issue, so declaring them with #property or #public doesn't change it.
Inside a constructor it's good practice to access variables declared with #property using underscore instead self to avoid side effects.
Let's try to access the variables.
File: Cow.h
#import "Animal.h"
#interface Cow : Animal
#end
File: Cow.m
#import "Cow.h"
#include <objc/runtime.h>
#implementation Cow
-(id)init {
self=[super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
//iPrivate = #"iPrivate"; // compiler error: variable is private
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
self.iPublic2 = #"iPublic2"; // using self because the backing ivar is private
//iNotVisible = #"iNotVisible"; // compiler error: undeclared identifier
//_iNotVisible2 = #"iNotVisible2"; // compiler error: undeclared identifier
//iNotVisible3 = #"iNotVisible3"; // compiler error: undeclared identifier
}
return self;
}
#end
We can still access the not visible variables using the runtime.
File: Cow.m (part 2)
#implementation Cow(blindAcess)
- (void) setIvar:(NSString*)name value:(id)value {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
object_setIvar(self, ivar, value);
}
- (id) getIvar:(NSString*)name {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
id thing = object_getIvar(self, ivar);
return thing;
}
-(void) blindAccess {
[self setIvar:#"iNotVisible" value:#"iMadeVisible"];
[self setIvar:#"_iNotVisible2" value:#"iMadeVisible2"];
[self setIvar:#"iNotVisible3" value:#"iMadeVisible3"];
NSLog(#"\n%# \n%# \n%#",
[self getIvar:#"iNotVisible"],
[self getIvar:#"_iNotVisible2"],
[self getIvar:#"iNotVisible3"]);
}
#end
Let's try to access the not visible variables.
File: main.m
#import "Cow.h"
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
#autoreleasepool {
Cow *cow = [Cow new];
[cow performSelector:#selector(blindAccess)];
}
}
This prints
iMadeVisible
iMadeVisible2
iMadeVisible3
Note that I was able to access the backing ivar _iNotVisible2 which is private to the subclass. In Objective-C all variables can be read or set, even those that are marked #private, no exceptions.
I didn't include associated objects or C variables as they are different birds. As for C variables, any variable defined outside #interface X{} or #implementation X{} is a C variable with file scope and static storage.
I didn't discuss memory management attributes, or readonly/readwrite, getter/setter attributes.

Properties in Objective c. copy and retain

What I have read from the apple document retain will increase the retain count by 1 , and release will decrease by 1. This is very much clear to me.
But In the case of copy and retain i am a bit confused.
Let me explain with the code i am trying.
property ---
#property(nonatomic, retain) NSMutableString *a;
#property(nonatomic, copy) NSMutableString *b;
#synthesize a = _a ,b = _b
a=[[NSMutableString alloc]initWithString:#"Hello Ankit"];
NSLog(#"a memory location A - %p", &a );
b=[[NSMutableString alloc]initWithString:#"Hello Nigam"];
NSLog(#"a memory location B- %p", &b );
c= [[NSMutableString alloc]initWithString:#"Ankit Nigam"];
NSLog(#"a memory location C %p",&c);
NSMutableString *temp =[[NSMutableString alloc]initWithString:#"hey"];
NSLog(#"temp = %# %p",temp,&temp);
self.b = temp;
NSLog(#"B is now %# %p",self.b,&b);
self.a = temp;
NSLog(#"A is now %# %p",self.a,&a);
And i get the output as -- - -
2012-05-10 03:24:34.756 retainCountTest[2655:f803] a memory location A - 0x6d314fc
2012-05-10 03:24:34.757 retainCountTest[2655:f803] a memory location B- 0x6d31500
2012-05-10 03:24:34.764 retainCountTest[2655:f803] a memory location C 0x6d31504
2012-05-10 03:24:34.764 retainCountTest[2655:f803] temp = hey 0xbfffdd04
2012-05-10 03:24:34.764 retainCountTest[2655:f803] B is now hey 0x6d31500
2012-05-10 03:24:34.765 retainCountTest[2655:f803] A is now hey 0x6d314fc
But as per I understand from the Doc the retain object must have the same memory address , where as copy object will create a new object with different memory location.
Again when i change the logs to ---
self.b = temp;
NSLog(#"B is now %# %p",self.b,&_b);
self.a = temp;
NSLog(#"A is now %# %p",self.a,&_a);
It return me a complete different memory location for both the object.
2012-05-10 03:28:49.905 retainCountTest[2688:f803] a memory location A - 0x6d4a4ac
2012-05-10 03:28:49.906 retainCountTest[2688:f803] a memory location B- 0x6d4a4b0
2012-05-10 03:28:49.907 retainCountTest[2688:f803] a memory location C 0x6d4a4b4
2012-05-10 03:28:49.907 retainCountTest[2688:f803] temp = hey 0xbfffdd04
2012-05-10 03:28:49.908 retainCountTest[2688:f803] B is now hey 0x6d4a4c0
2012-05-10 03:28:49.908 retainCountTest[2688:f803] a is now hey 0x6d4a4bc
Can any help me to understand the complete concept of these retain and copy. Also why I am getting these unexpected results.
Thanks a lot.
A property is just a declaration that allows for setters, getters, and dot-syntax accessors (interface variable hiding).
It does absolutely nothing on its own but allow you to use -[myInstance myProperty] to get the variable or use -[myInstance setMyProperty:] to set it (yes, the method name is auto-assigned to -setProperty: and -property).
When declaring a property, you have three categories - thread locking, access control, and memory management. You can only pick one of the modifiers for each category and if you do not pick one, it's auto-assigned to one automatically.
#property (<thread locking>, <access control>, <memory management>) id property;
The first category can either be atomic or nonatomic. The atomic modifier forces an #synchronized(myInstance) lock on the variable, to allow thread safety. The nonatomic does not use a synchronized-block, and is NOT thread safe. If you do not use either, it is automatically set to atomic.
The second category can either be readonly or readwrite. The readwrite modifier allows the property to be modified as well, and allows auto-generation of the -setProperty: method. When the readonly modifier is used, you cannot use the -setProperty: method. You must use the internal variable from within the object to set the variable directly.
The third category can either be assign, retain, and copy. The assign modifier means the internal object pointer is set to the pointer passed to the -setProperty: message. The retain modifier assigns the passed pointer and passes a -retain to the object.
The copy modifier does a straight-up clone of the object- a new pointer to a new object at a new address in the memory. This sets the internal object pointer to the copy of the passed object, by calling -copy on the passed object. The default modifier is assign, and the compiler will warn you if you do not set the memory management category modifier on an object - because an assign modifier on an object is frowned upon (unless explicitly declared).
For an example on -copy, look at this:
- (void)setProperty:(GXMyObject *)property {
// This points to the original passed object.
GXMyObject *original = property;
// This points to a copy of the passed object.
CGMyObject *copied = [property copy];
// This points to yet another copy of the passed object-
// Independent of the other copies and original.
_property = [property copy];
// The anotherProperty is now different on this copy
// than on the original and the other copies.
_property.anotherProperty = 4;
// This will prove that they are all individual objects.
NSLog(#"%p, %p, %p", original, copied, _property);
}
There is an optional method name declaration modifier and is used like so: getter = myCustomPropertyGetter and setter = myCustomPropertySetter: (The colon : at the end of the setter method name is required because it denotes that an argument must be passed).
The second half of this is the property synthesizer or dynamizer. Once a property is declared (for example, myView) like so:
#property (nonatomic, retain) NSView *myView;
You would either: define the setter and getter yourself; #synthesize the setter and getter; #dynamic the property to say that it exists in a category or the main class, or may be added at runtime (not a fun idea, mind you, and could cause bad runtime exceptions).
The first example, writing the methods yourself would look like this:
// In Apple's LLVM 3.1 Compiler, instance variables can be added
// within {} below the #implementation as well as the #interface,
// and in private categories (#interface GXMyClass ()) like before.
#implementation GXMyClass {
// The internal object pointer is prefixed with an _ to avoid name confusions.
NSView *_myView;
}
- (NSView *)myView {
return _myView;
}
- (void)setMyView:(NSView *)myView {
_myView = [myView retain];
}
#end
The second example would be to auto-synthesize it using the #synthesize directive:
#implementation GXMyClass
// In the new Apple LLVM 3.1 Clang compiler, the = operator when used
// next to the #synthesize directive declares an internal private
// variable and automatically sets to that variable.
#synthesize myView = _myView;
// The internal variable name is now myOtherView, because we did not use the
// = operator to assign an internal variable name to the property.
#synthesize myOtherView;
#end
Under the last example, perhaps the most confusing, because it requires the use of the #dynamic directive, you require something of a category or a runtime method addition:
#interface GXMyClass (InternalMethods)
#end
#implementation GXMyClass
// The = assignment operator does not work here.
#dynamic myView;
#end
#implementation GXMyClass (InternalMethods)
- (NSView *)myView {
return [self methodThatReturnsAnNSView];
}
- (void)setMyView:(NSView *)myView {
[self methodThatAcceptsAnNSViewArgument:myView];
}
#end
The #property declaration requires one of the three above declarations to be present- it does not do anything on its own. What it DOES allow, however is dot-syntax accessors (Java-like accessors for setting and getting properties).
For example, #property (copy) NSString *myName; could be accessed using -[myObject myName] and set using -[myObject setMyName:].
Now it can be set using myObjectInstance.myName = #"Bob"; and gotten using myObjectInstance.myName. Utilizing all the above concepts, one could create an object such as this one:
// The GXBufferQueue is a queue which buffers all requests, till they are read
// asynchronously later. The backing store is an NSMutableArray to which all
// buffer writes are appended to, and from which the first object is pulled and
// returned when the buffer is read to.
#interface GXBufferQueue
#property (nonatomic, readwrite, copy, setter = write:, getter = read) id buffer;
+ (GXBufferQueue *)queue;
#end
#implementation GXBufferQueue {
// This queue is an internal array and is 'tacked on' to the #implementation
// so no others can see it, and it can be marked #private so subclasses cannot
// use it. It is also good code practice to have #interfaces composed of only
// #properties, setters, and getters, rather than expose internal variables.
NSMutableArray *_internalQueue;
}
+ (GXBufferQueue *)queue {
return [[[GXBufferQueue alloc] init] autorelease];
}
- (id)init {
if((self = [super init])) {
_internalQueue = [[NSMutableArray alloc] init];
}
}
- (void)write:(id)buffer {
[_internalQueue addObject:buffer];
}
- (id)read {
if(!(_internalQueue.count > 0)) return nil;
id buffer = [_internalQueue objectAtIndex:0];
[_internalQueue removeObjectAtIndex:0];
return buffer;
}
#end
Note: This code was in no way tested.
Now that you have a GXBufferQueue, all the following works:
GXBufferQueue *queue = [GXBufferQueue queue];
// Option One: using the traditional message syntax:
[queue write:#"This will be now added to the buffer."];
NSLog(#"Now the string written to the queue will be read \
and removed from the queue, like a stack pop. ", [queue read]);
// Option Two: using the new dot-syntax accessors:
queue.buffer = #"As clunky as this looks, it works the same as above.";
NSLog(#"These lines work just the same as the ones above: ", queue.buffer);
As you can see, there's a lot possible with properties and a lot more that can be done with them than just variable declaration. If there are any questions or anything the community would like me to add/rectify to/in the post, please leave a comment! :D
Yes, retainCount is useless-- don't call it-- and assuming that copy will always return a new instance is incorrect.
If an immutable object is sent copy, it will typically be implemented as:
- copy { return [self retain]; }
I.e. there is no need to make an actual copy since the contents can't change.
Of course, since you are mucking about with static, compiled into the binary, strings, the implementation is likely closer to:
- retain { return self; }
- copy { return self; }
- (void)release { ; }
- (void)dealloc { ; }
Maybe -- all of the above are implementation details that may change at any time. The bottom line, though, is that all of the above fulfills the contract of retain/release/copy/etc...

Nested factory methods in Objective-C

What's the best way to handle memory management with nested factory methods, such as in the following example?
#interface MyClass : NSObject {
int _arg;
}
+ (MyClass *) SpecialCase1;
+ (MyClass *) SpecialCase2;
+ (MyClass *) myClassWithArg:(int)arg;
- (id) initWithArg:(int)arg;
#property (nonatomic, assign) int arg;
#end
#implementation MyClass
#synthesize arg = _arg;
+ (MyClass *) SpecialCase1
{
return [MyClass myClassWithArg:1];
}
+ (MyClass *) SpecialCase2
{
return [MyClass myClassWithArg:2];
}
+ (MyClass *) myClassWithArg:(int)arg
{
MyClass *instance = [[[MyClass alloc] initWithArg:arg] autorelease];
return instance;
}
- (id) initWithArg:(int)arg
{
self = [super init];
if (nil != self) {
self.arg = arg;
}
return self;
}
#end
The problem here (I think) is that the autorelease pool is flushed before the SpecialCaseN methods return to their callers [Edit: apparently not - see comments below]. Hence, the ultimate caller of SpecialCaseN can't rely on the result having been retained. (I get "[MyClass copyWithZone:]: unrecognized selector sent to instance 0x100110250" on trying to assign the result of [MyClass SpecialCase1] to a property on another object.)
The reason for wanting the SpecialCaseN factory methods is that in my actual project, there are multiple parameters required to initialize the instance and I have a pre-defined list of "model" instances that I'd like to be able to create easily.
I'm sure there's a better approach than this.
[Edit: #interface added per request.]
Why do you think the autorelease pool is being flushed?
The autorelease pool is not flushed in cocoa-touch unless either you flush it, or control is returned back to the event loop.
From the iPhone Memory Management Guide
The Application Kit automatically
creates a pool at the beginning of an
event cycle (or event-loop iteration),
such as a mouse down event, and
releases it at the end, so your code
normally does not have to worry about
them.
The error describes the problem exactly: copyWithZone is called and it's not implemented in MyClass. Check out the attributes or the implementation of the property it's assigned to (see if it's copying). Also, copyWithZone will be called if the instance of MyClass is used as a key to an NSDictionary. Here's some info on implementing copyWithZone.

Property vs. instance variable

I'm trying to understand how strategies some folks use to distinguish instance vars vs. properties. A common pattern is the following:
#interface MyClass : NSObject {
NSString *_myVar;
}
#property (nonatomic, retain) NSString *myVar;
#end
#implementation MyClass
#synthesize myVar = _myVar;
Now, I thought the entire premise behind this strategy is so that one can easily distinguish the difference between an ivar and property. So, if I want to use the memory management inherited by a synthesized property, I'd use something such as:
myVar = #"Foo";
The other way would be referencing it via self.[ivar/property here].
The problem with using the #synthesize myVar = _myVar strategy, is I figured that writing code such as:
myVar = some_other_object; // doesn't work.
The compiler complains that myVar is undeclared. Why is that the case?
Thanks.
Properties are just setters and getters for ivars and should (almost) always be used instead of direct access.
#interface APerson : NSObject {
// NSString *_name; // necessary for legacy runtime
}
#property(readwrite) NSString *name;
#end
#implementation APerson
#synthesize name; // use name = _name for legacy runtime
#end
#synthesize creates in this case those two methods (not 100% accurate):
- (NSString *)name {
return [[_name copy] autorelease];
}
- (void)setName:(NSString *)value {
[value retain];
[_name release];
_name = value;
}
It's easy now to distinguish between ivars and getters/setters. The accessors have got the self. prefix. You shouldn't access the variables directly anyway.
Your sample code doesn't work as it should be:
_myVar = some_other_object; // _myVar is the ivar, not myVar.
self.myVar = some_other_object; // works too, uses the accessors
A synthesized property named prop is actually represented by two methods prop (returning the current value of the property) and setProp: (setting a new value for prop).
The self.prop syntax is syntactic sugar for calling one of these accessors. In your example, you can do any one of the following to set the property myVar:
self.myVar = #"foo"; // handles retain/release as specified by your property declaration
[self setMyVar: #"foo"]; // handle retain/release
_myVar = #"Foo"; // does not release old object and does not retain the new object
To access properties, use self.propname. To access instance variables use just the instance variable's name.
The problem with using the #synthesize myVar = _myVar strategy, is I figured that writing code such as:
myVar = some_other_object; // doesn't work.
The compiler complains that myVar is undeclared. Why is that the case?
Because the variable myVar is undeclared.
That statement uses the syntax to access a variable, be it an instance variable or some other kind. As rincewind told you, to access a property, you must use either the property-access syntax (self.myVar = someOtherObject) or an explicit message to the accessor method ([self setMyVar:someOtherObject]).
Otherwise, you're attempting to access a variable, and since you don't have a variable named myVar, you're attempting to access a variable that doesn't exist.
In general, I name my properties the same as my instance variables; this is the default assumption that the #property syntax makes. If you find you're fighting the defaults, you're doing it wrong (or your framework sux, which is not the case for Cocoa/Cocoa-touch in my opinion).
The compiler error you're getting is because property use always has to have an object reference, even inside your own class implementation:
self.stuff = #"foo"; // property setter
[stuff release]; // instance variable
stuff = #"bar"; // instance variable
return self.stuff; // property getter
I know that many Cocoa programmers disagree, but I think it's bad practice to use properties inside your class implementation. I'd rather see something like this:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
[stuff release];
stuff = [theStuff copy];
// do something else
}
than this:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
self.stuff = theStuff;
// do something else
}
I prefer to do memory management as explicitly as possible. But even if you disagree, using the self.stuff form will clue in any experienced Objective-C programmer that you're calling a property rather than accessing an instance variable. It's a subtle point that's easy for beginners to gloss over, but after you've worked with Objective-C 2.0 for a while, it's pretty clear.
Don,
According to the "rules", you should call Release for every Copy, Alloc, and Retain. So why are you calling Release on stuff? Is this assuming it was created using Alloc, Copy, or Retain?
This brings up another question: Is it harmful to call Release on a reference to an object if it's already been released?
Since Apple reserves the _ prefix for itself, and since I prefer to make it more obvious when I am using the setter and when I am using the ivar, I have adopted the practive of using a prefix of i_ on my ivars, so for example:
#interface MyClass : NSObject {
NSString *i_myVar;
}
#property (nonatomic, retain) NSString *myVar;
#synthesize myVar = i_myVar;
i_myVar = [input retain];
self.myVar = anotherInput;
[i_myVar release]
Since it is quite important to know when you are using the setter and when you are using the ivar, I find the explicitly different name is safer.
In your question, it should be:
self.myVar = #"Foo"; // with setter, equivalent to [self setMyVar:#"Foo"]
and
_myVar = some_other_object; // direct ivar access - no memory management!
Remember that you should not use setters/getters in init/dealloc, so you need to do your direct ivar access (and careful memory management) iin those methods.
what's wrong with simply using
#interface MyClass : NSObject
#property NSString *prop;
#end
nonatomic and retain are not required, retain is the default, and atomic/nonatomic isn\t important unless XCode tells you with a warning.
it is NOT necessary to declare the iVar, one will be created for you named _prop, if you really want to use one (i don't see why to be honest)
#synthesize is NOT required.
when (and you should) using ARC you don't have to bother with retain and release either.
keep it simple !
furthermore, if you have a method like this one
- (void)aMethod:(NSString*)string
{
self.prop = string;
// shows very clearly that we are setting the property of our object
_aName = string;
// what is _aName ? the _ is a convention, not a real visual help
}
i would always use properties, more flexible, easier to read.