views:

90

answers:

3

I'm picking up ObjC and Cocoa, which is also my first serious foray into programming in general.

I'm having trouble with the differences between initWith methods, which are called on instances, and factory methods, which are called on classes.

Firstly, why are they called "factory" methods, and is there a proper term for what I've dubbed "InitWith" methods?

Secondly, what's the functional difference? Is it just the memory management implications (that factory methods return an autoreleased object)?

For example, what's the real difference between [NSString stringWithString: (NSString*)aString] and [[NSString alloc] initWithString: (NSString*)aString]?

A: 

On your example of [[NSString alloc] initwithString: (NSString *)aString];

When you do an alloc you are placing a space for the String in the memory hence the alloc. you then tell it to initialize with the string equal to aString. the (NSString *) is an identifier for the object type so you are telling it aString is declared to be an NSString.

I usually do something like

NSString * aString = @"String value";

declares what aString is equal to.

If you alloc something into memory in order to manage it you will need to release it at the correct time such as the -(void) dealloc {} section of your code

Everything about NSString can be explained in this documentation from Apple NSString

Rugluds
This goes for both of you, Rugluds and Audacitor: You don't need to include the `(NSString *)` when sending the `initWithString:` message. Only the declaration of the method needs it (to specify what type the method expects). When you include it as part of a message, you are casting the `aString` value to `NSString *`. If `aString` is an `NSString *`, then this does nothing and is unnecessary; if it is something else, then the cast will still do nothing useful: It will shut up the compiler, but you'll crash at run time.
Peter Hosey
A: 

The main difference is that [NSString stringWithString: (NSString*)aString] returns an autoreleased string whose memory management you need not worry about, whereas [[NSString alloc] initWithString: (NSString*)aString] returns a string which you are responsible for releasing. Basically the former is a shortcut for the latter, plus autorelease.

andyvn22
well, "whose memory management you need not worry about" isn't quite the whole story and might lead a newcomer astray...For example, if you are assigning the result to an instance variable (1) then you'll want to retain the result from a class method or you will find that when you access your instance var it will go away. This is a classic mistake for those new to ObjC/Cocoa.(1) an instance variable that is not a property with synthesized setter is setup to retain via the property attributes.
Dad
Another common mistake is confusing instance variables with properties. The memory-management policy (e.g., `retain`) you declare for a property has no effect on the instance variable; assignments to the instance variable always happen with no side effects, including no retentions or copies. Therefore, when assigning to an ivar, you need to retain or copy the value yourself. Only assigning to a property can do that for you.
Peter Hosey
+1  A: 

The difference between the methods is described in Cocoa's object ownership policy. You own the object returned from -initWithString: and so must release it, but you don't own the object returned from +stringWithString and so do not need to release it (furthermore, if you do want to gain ownership of it, you must retain it).

Factory methods are called that because they return an already-created object for you, usually with parameters you provide that are used to configure the object, for the convenience of the programmer.

Preston