Object retain behavior of Objective-C class methods - objective-c

What's the best practice for retaining and releasing objects passed to class methods?
For instance, if you have a "class variable" declared like so:
static NSString *_myString = nil
...is the right thing to do this:
+ (void)myClassMethod:(NSString *)param {
_myString = param;
}
... which has the drawback that the caller needs to maintain a nonzero retain count on param lest it be released prematurely. Alternatively one could do this:
+ (void)myClassMethod:(NSString *)param {
[_myString autorelease];
_myString = [param retain];
}
...which has the drawback that without a corresponding class-level dealloc call it will leak memory. Or should this sort of class variable chicanery be avoided completely, perhaps with a singleton class that manages the lifetime of these sorts of objects in a more conventional way?
Here are Apple's docs on creating a singleton instance.
The code that I'm working with is the very slick (but still new) Objective Resource project (http://www.iphoneonrails.com/).

Retain and release, absolutely. It's not a leak because the only time when a class's dealloc would be called is when the program ends — at which time the memory will be freed anyway. Doing it the first way would be more hassle and goes against the Cocoa memory-management guidelines.
As for whether it should be a class method or a singleton: Classes themselves generally should not have a lot of independent functionality. They just weren't designed that way in Objective-C, as you can see from the lack of class variables. Class methods should generally deal with creating and managing instances, and sometimes storing shared properties or defaults for all instances. The actual functionality of a class should go into instances. That's the convention in Objective-C.
(Of course, there is no Objective-C God and you're free to ignore conventions, but that's the general wisdom.)

Also, in the case of NSString or any class that has mutable variants (like NSArray or NSDictionary), I'd strongly recommend copying the parameter instead of retaining it. If the string the caller passed you was an NSMutableString, its value could change later, and it will change in your class as well. This is probably not what you want, so I'd advise doing this:
+ (void)myClassMethod:(NSString *)param {
[_myString release];
_myString = [param copy];
}
The copy method makes a copy and sets the retain count to 1, so you're all set as far as retaining the variable is concerned. And, as an extra bonus, if the caller does pass you an NSString, that class is smart enough to know that its value can't change, so it simply retains itself to avoid making a copy of the object. How clever is that?

Related

Fully deallocating an Objective-C singleton

I'm new to writing singletons and I have to use one for a current iOS project. One of the requirements is that it can be killed. I know this goes against the design of a singleton, but is this something that should/could be done?
Of course it could be done, but if you're looking for an object that can be created, and then released when not needed... that sounds like a regular object. :)
Generally singletons control their own lifecycles. You're going to get one-sided discussion here unless you say more about the two requirements (one, that you use a singleton, and two, that it can be released at will), and why they both make sense in your case.
It might be because the singleton wraps some other resource that is inherently unique (like a file resource or network connection). If this is true, then generally the singleton is the "manager" of that resource, and you'd expose control of that resource via the singleton's interface.
Or it might be because the singleton object holds on to a ton of memory (a buffer of some sort), and you want to be sure that's flushed as necessary. If this is the case, then you can be smarter about each of its methods creating and releasing memory as necessary, or you can have the singleton listen for the low memory system notifications and behave appropriately.
Essentially, I'd be hard pressed to construct a case where it really made sense for the singleton object itself to be released. A single basic object takes only a handful of bytes in memory, and hurts no one by hanging around.
I know this goes against the design of a singleton
It also goes against the usual memory management patten in Objective-C. Normally, an object gets to retain another object to prevent it from being destroyed, and to release it to allow the object to be destroyed. Explicitly destroying an object, though, isn't something that other objects get to do.
Consider what would happen if object A gets the shared instance S1 of a singleton class S. If A retains S1, S1 will continue to exist even if some class method releases S and sets the global variable that points to the shared instance to nil. When the class later creates a new shared instance, S2, there will be two instances of S, namely S1 and S2. This violates the property that defines the singleton in the first place.
You might be able to get around this problem by overriding -retain and maybe swizzling -release, but that seems like a lot of complexity to solve a problem that shouldn't exist in the first place.
A possible alternative is to reset your shared object instead of trying to destroy it. You could set all it's attributes to some known (possibly invalid) state if you want, and then have a class method the re-initializes the shared object. Just be aware of the effect of all that on any objects that might be using the shared object.
Just about every singleton I've ever written (save for totally UI centric controllers) end up being refactored into not being singletons. Every. Single. One.
Thus, I've stopped writing singletons. I write classes that maintain state in instances, as any normal class should, and do so in isolation from other instances. If they are notification heavy, they always pass self as the notifying object. They have delegates. They maintain internal state. They avoid globals outside of truly global state.
And, often, there may be exactly one instance of said class in my app(s). That one instance acts like a singleton and, in fact, I might even create a convenient way of getting a hold of it, likely through the App's delegate or through a class method (that might even be named sharedInstance sometimes).
Said class includes tear-down code that is typically divided in two pieces; code to persist current state for restoration later and code that releases instance associated resources.
Convenient like a singleton. Ready to be multiply instantiated when needed.
Sure no problem. You provide a new class method: [MyClass killSingleton]; That method releases the singleton and sets its internal reference to nil. The next time someone asks [MyClass sharedSingleton], you go through the same steps you did before to create it.
EDIT: actually, in the old days such a routine could have overridden the release selector, and refused to go away. So as the first comment below states, this is an object with static scope - its kept alive through a static variable keeping a retain count of 1 on the object. However, by adding in a new class method to nil out that ivar (under ARC), thereby releasing it, achieves the desired result. Control over instantiating and releasing the static object is completely done via class methods, so is easy to maintain and debug.
It's against the concept of Singleton, but it can be implemented the following way for an ARC based project
//ARC
#interface Singleton : NSObject
+ (Singleton *)sharedInstance;
+ (void)selfDestruct;
#end
#implementation Singleton
static Singleton *sharedInstance = nil;
+ (Singleton *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[Singleton alloc] init];
}
return sharedInstance;
}
+ (void) selfDestruct {
sharedInstance = nil;
}
#end
//This can be implemented using bool variable. If bool no create new instance.
#interface Singleton : NSObject
+ (Singleton *)sharedInstance;
#end
#implementation Singleton
static Singleton *sharedInstance = nil;
+ (Singleton *)sharedInstance {
if (!keepInstance) {
sharedInstance = [[Singleton alloc] init];
keepInstance = YES;
}
return sharedInstance;
}
#end
I needed to clear out the singleton so I ended up doing the following:
- (void)deleteSingleton{
#synchronized(self) {
if (sharedConfigSingletone != nil) {
sharedConfigSingletone = nil;
}
}
}
Hope it helps.

How does accessing ivars directly differ from using an accessor?

So in some of the codes I see, they access an objects ivar directly instead of using accessors . What are the advantages of using them instead of accessors?
So how would this
thing = object->ivar
differ from this?
thing = object.ivar
Thanks.
First let me say, I totally loathe the Objective-C dot notation. It sacrifices understandability for brevity and that is a bad thing. In fact, the other two answers here both show evidence of the kind of confusion dot notation introduces.
Having got the rant out of the way, I'll now try to answer the question.
Under the hood, Objective-C objects are implemented as pointers to C structs. This is why
obj->ivar
sometimes works. Given that it's a C struct
(*obj).ivar
should also work exactly as you would expect for C. Having said that, you can make ivars private or protected, in which case using the above outside a scope where they are visible will cause a compiler error.
The dot operator when applied to an Objective-C object (which is a pointer don't forget) has a totally different meaning. It's syntactic sugar for sending an accessor message to the object meaning that:
foo = obj.property;
obj.property = foo;
is identical in effect to
foo = [obj property];
[obj setProperty: foo];
That is all there is to dot notation. If you go through your code changing all instances of the first form to instances of the second form, you have done everything the compiler does wrt dot notation.
In particular
you do not need a declared #property to use dot notation. You can declare the set and get accessors in the traditional way as Objective C methods, although it is definitely best practice to use #property declarations for things that are logically properties.
you do not need a backing instance variable. There's no reason why your getters and setters can't calculate values.
Given the above, the major difference between obj->ivar and obj.ivar is that the former modifies the ivar directly and latter invokes an accessor, this means that the latter can do any memory management stuff needed (retains, releases, copies etc) and can also invoke key value observing.
This is one thing with a huge difference between c/c++ and objective-c.
In C/C++ the . accesses the variable directly and the -> accesses the variable if it's a pointer to the variable, so basically it is the same.
In Objective-C the . is a shortcut to access the property using the setter and getter function and it is always using those functions. You can't access ivars with it if there is no property with that name.
Some say it's "dirty" to allow direct access to the variables. If more people work on the code it's "cleaner" to use accessors because it might be easier to debug where variables are changed since you can always break in the setter.
You can even do "bad" things with it, like:
NSArray *array = [NSArray alloc] init];
int count = array.count;
array.release;
this will technically work, because the array.release is a shortcut for [array release] but it is bad style to use . for other things then properties.
The advantage of properties is that they call methods that work with your ivars, in stead of calling the ivars directly, so you can do things like this:
-(void)setFrame:(CGRect)frame
{
if([self frameIsValid:frame])
{
if(self.flipsFrames)
{
frame.size = CGSizeMake(frame.size.height,frame.size.width);
}
[super setFrame:frame];
[delegate viewSubclass:self ChangedFrameTo:frame];
}
}
Four advantages shown here are:
The possibility to override
The possibility to check a given value
The possibility to alter a given value (use with caution)
A way to react to calls
Another advantage:
-(NSInteger) amountOfMinutes
{
return amountOfSeconds * 60;
}
You can use 1 ivar for multiple properties, saving memory and preventing/reducing redundancy, while keeping useful different formats.
There's not really an advantage to using ivars, except when you don't want to use a property so your class is more encapsulated. That does not make it impossible to reach, but it makes it clear it isn't supposed to be reached.
All ivars are private. There is no way to access them directly from outside the object. Therefore, both of your code samples are equivalent, in ObjC terms.
When you call object.ivar, what you are really doing is calling object's ivar selector. This may be either a getter method that you wrote yourself, or more likely, a synthesized getter method that you created with #synthesize.
thing, however, is an ivar. Your code would be calling the ivar selector on object and assigning the result directly to your instance's thing ivar.
If you had instead written it as self.thing = object.ivar, then you would be using your instance's setter method to assign to thing.
Some of the advantages of using accessors (specifically, synthesized properties) in ObjC are KVO/KVC compliance; better concurrency support; access control (readonly, readwrite); as well as all of the advantages that accessors give you in any other OO language.

Do I need getters and setters if i'm depending on garbage collection in objective-c

New to Cocoa and Objective-c.
Do I need getters and setters if I'm depending on garbage collection?
For example is it safe to just modify instance variables directly without the dot syntax?
And in the dealloc method can I sent them to nil instead of release (or do I even have to release them)?
Property (Getters and setters) is a mean of encapsulation, and ivar is an implementation detail.
Accessing via properties allow you to change the internal design while keeping the interface unchanged.
Whether the program has GC enabled or not, you shouldn't access ivar directly externally (internally is fine).
(Also, the -dealloc method is ignored if GC (not ARC) is enabled. You could implement -finalize. But the GC should be smart enough to clean the no-longer-needed ivars, whether to set them to nil or not.)
From within the class itself you can directly modify the private variables of course. Think about accessors mainly to expose a public interface and avoid other classes to modify directly your object. This comes from the Object Oriented Paradigm and not with the memory management.
About the release it is better to understand clearly how it works using the retain count and what have a role on that count. Some method like init increase retains the object and some other do not. A lot static methods that return new ready to use object like imageWithNamed: return an autorelease object that you have to retain explicitly to own them.
The best is to release and set to nil when you have transfer the ownership to another object (ex. an array)
ex.
NSString *myName = #"zgueb";
NSArray *myFamily = [[NSArray alloc] initWithObjects:myName, nil];
// now myName is retained by myFamily, i can release it
[myName release];
myName = nil;
Is it clear.
Vince.

is it good form to release self in an init method when that method allocates and returns something else?

In my code, I have something that looks like this:
#implementation MyClass
- (id) initWithType:(NSInteger)type {
[self release];
if (type == 0) {
self = [[MyClassSubclass1 alloc] init];
} else {
self = [[MyClassSubclass2 alloc] init];
}
return self;
}
//...
#end
which I think handles any potential memory leaks. However, I have seen code out there that does something similar, except it doesn't release self before reassigning it to another newly allocated instance. Is it not necessary to release self here or is the other code I've seen incorrect?
Your code looks technically correct, from a memory management perspective. Replacing self with a different alloc'd object loses the pointer to the original object, and nobody else will be able to release it, which would cause a leak. Try commenting out the release call and run it with Leaks in Instruments.
Just be cautious about opening this particular can of worms — Foundation.framework (part of Cocoa) uses class clusters for collections and strings, but doing so is a fairly advanced concept. A better approach might be to have a class method for each subclass, using the AbstractFactory pattern.
In any case, determining the subclass type based on an integer is a bad idea — any change in mapping from type to class will break dependent code. If you're going that way, why not just pass in the class object itself?
This looks like poor use of object-oriented design.
If you're creating a different instance depending on a type variable, then why don't you have subclasses for those types?
It would be much cleaner to define a base class with all the common functionality, and a subclass for each "type" variation.
What does the class do? We might be able to point you in the right direction.
Code-wise, your example code is correct, but it's generally bad practice to replace the instance with a different instance. Unless the init method is a factory method re-using instances or a singleton initializer, avoid releasing self en-lieu of another instance.

Why are alloc and init called separately in Objective-C?

Note: I'm relatively new to Objective-C and am coming from Java and PHP.
Could someone explain to me why I always have to first allocate and then initialize an instance?
Couldn't this be done in the init methods like this:
+ (MyClass*)init {
MyClass *instance = [MyClass alloc];
[instance setFoo:#"bla"];
return instance;
}
+ (MyClass*)initWithString:(NSString*)text {
MyClass *instance = [MyClass init];
[instance setFoo:text];
return instance;
}
...
Is this just a relict from the old C days or is there something that I'm not seeing?
I know this isn't a problem as I could as well always call alloc and init, but since it's a bit tedious I'd like to at least know why I'm doing it.
I'm liking the expressiveness of the language so far, but this is something that I want to fully understand in order to think the Objective-C way.
Thank you!
+new ends up sending an +alloc message to the class and an -init message to whatever comes back from +alloc.
The reason that NeXT departed from Stepstone's convention of using the +new message (which was a Smalltalk idea) is that early on, they encountered situations where they wanted to be able to initialize the same object more than once.
Because creating an instance and initializing an instance are two separate jobs.
You send an alloc message to the class to get an uninitialized instance. You must then initialize the instance, and you often have several ways to do that. For example:
myStr = [[NSString alloc] init]; //Empty string
myStr = [[NSString alloc] initWithFormat:#"%#.%#", parentKeyPath, key];
myStr = [[NSString alloc] initWithData:utf16data encoding:NSUnicodeStringEncoding error:&error];
myStr = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:&error];
Each of these initializes the string in a completely different way. How you initialize the string depends on what you want to initialize it from.
Of course, nobody likes writing alloc and then init and then autorelease every time, so you usually have convenience methods (e.g., stringWithFormat:) that do all three steps for you.
Edit: For more on this topic, including essential insights from commenters, see my blog post “Reunification”.
See NSZone.
+alloc is a shortcut cut for +allocWithZone:, which is a mechanism Cocoa provides for optimizing memory allocation.
So you have the option to do something like this:
foo = [[NSString allocWithZone:MyZone] initWithString:#"Foo"];
foo2 = [foo copyWithZone:MyZone];
The idea behind memory zones is that if you have a large number of similar objects that are frequently allocated and deallocated it may more efficient to use a separate memory zone for those objects.
In order for zoning to be effective you'd want to have +allocWithZone: available to every NSObject subclass, hence you need to separate allocation and initialization. You can create and use all the shortcuts you want, like +new, but underneath it all you need an -init method that initializes an object that has already been allocated.
"Separating the allocation and initialization stages of instance creation provides many benefits. It’s possible to use any variation of the +alloc class method to allocate an instance and then use any available initializer with the new instance.This makes it possible to create your own initialization methods without needing to provide alternate implementations of all allocation methods.
New allocation methods are seldom created because the existing methods meet almost every need. However, one or more new initializers are created for almost every class. Due to the separation of allocation and initialization stages, initializer implementations only have to deal with the variables of new instances and can completely ignore the issues sur- rounding allocation.The separation simplifies the process of writing initializers. Furthermore, Cocoa standard initializers like -initWithCoder: work with instances regardless of the way memory for the instance was allocated.
One negative consequence of the separation of allocation and initialization is the need to be aware of conventions such as the designated initializer.You must know which methods are designated initializers and how to create and document new initializers in sub- classes. In the long run, using designated initializers simplifies software development, but there is an argument to be made that theTwo-Stage Creation pattern adds to the early learning curve for Cocoa developers."
(c) Cocoa Design Patterns by Erik M. Buck and Donald A. Yacktman
You don't have to. You can use [MyClass new]. This is similar to your hypothetical init method.
Basically, Objective-C, which didn't have garbage collection initially, separates the concept of memory allocation and class initialization. That's why there are two distinct methods. When you call alloc, you are explicitly allocating memory.
Most classes have what you are asking for. You have gotten answers before on why this is like it is and why you wouldn't always want to use this all the time but if you read the documentation to classes you will see many class methods that act this way and they are often used.
For NSString you have, for example:
+ (id)string // (Empty string)
+ (id)stringWithFormat:... // Formatted string (like you use)
+ (id)stringWithContentsOfURL:... // String populated with contents of URL
And so on. And you would then use this like: NSString *myString = [NSString stringWithFormat:#"Hello %#\n", userName];
Most other classes have this, like NSArray:
+ (id)array
+ (id)arrayWithContentsOfFile:...
+ (id)arrayWithContentsOfURL:...
+ (id)arrayWithObjects:...
You just need to read the documentation. :) And read the other replies on why you don't want to use this too much.
alloc : Memory is allocated/given to the object-reference. Now reference has the possession of the memory but has not done anything yet. This memory be empty(rarest case) or with some anonymous data.
alloc and init : Allocated memory is cleaned/emptied. Memory is initiated by zero bit.
alloc and initwithdata... : Allocated memory is initiated with desired data respected to properties of the class.
For example when you purchase a plot you get the possession. This plot is given to you as it is, ruined bricks or old house may be there. This is alloc.
When you clean your plot and remove all dirt and litter. This is alloc with init.
When you build that into some valuable house it becomes more meaningful to you. And it is alloc initwith...