objective-cclass-factory

UICololor class factory methods - when are they released


I'm reading about class factory methods in objective-c as a design pattern and have some confusion. I"m using UIColor's as my example for the question for simplicity but if things vary with other class factory methods let me know. The basic concept:

UIColor *white = [UIColor whiteColor]; 

I understand that this combines allocation and initialization. Some of the documentation I've read is older before automatic reference counting and refers to it being made with autorelease(something i'm not familiar with not having used MRC). I"m trying to understand how this relates to automatic reference counting and singletons. If I do this for example:

UIColor *whiteSquare = [UIColor whiteColor]; 
UIColor *whiteBall = [UIColor whiteColor]; 

Am i retaining just one object sort of like a singleton?

When is it released? when all objects that are composed of whiteColor go out of scope or are set to nil?

I referred to Class methods which create new instances but it was a bit confusing for me with some answers referring to ARC and some not.

The final answer in the above thread says:

"The modern way to do this with ARC and the latest complier is:

+ (instancetype) myClassWithString:(NSString *)string {
return [[MyClass alloc] initWithString:string];
}

No need to autorelease with ARC."

I'm just unclear on what this auto release implies. I read some apple documentation and they indicated this was a part of the picture. By the above example if this is true it would create multiple instances of the variable if this is true. The method is a class method but the above code implies its not a static assignment.

Is that all a class factory method means? Its returns an object like any other initialization but its a static or class method and it combines allocation and initialization? How does auto release play into it? I'm having trouble understanding why it cant just create one white Color for all objects to share. This seems to be more efficient. But what led me to ask this question is to understand the design pattern of class factory methods and its obviously done one way or the other.

In ARC and autorelease the top answer says "Autorelease as a mechanism is still used by ARC, furthermore ARC compiled-code is designed to interoperate seamlessly with MRC compiled-code so the autorelease machinery is around." So i'm still stuck wondering is there one or two copies if i ask for whiteColor twice for two objects. And when is it released. In the above code example it appears to be an object like any other but in the above post its different.

the second answer in the above thread says "autorelease is used for returned function object so the caller don't take ownership and callee will release the object in the future." so again what is the motivation here? does class UIColor wish to only have one object for all callees? How does this factor into the class factory design pattern?

the class reference for UIColor https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UIColor_Class/index.html just says for the function whiteColor: "Return Value The UIColor object."

and i'm not finding an answer there.

In doing a little more research i see "Another purpose for a class factory method is to ensure that a certain class (NSWorkspace, for example) vends a singleton instance. " https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/ClassFactoryMethods/ClassFactoryMethods.html

That is the result of further research. I'm going to move any other questions to another post.


Solution

  • Factory methods like [UIColor whiteColor] do not necessarily allocate every time. They might be handing out the same instance every time (a singleton). So it's very much possible that the returned object is never deallocated. When you call [UIColor whiteColor] several times you might get distinct objects each time or you might get the same object every time, that's not defined. But it's not something you need or should care about (usually).

    Actually, there is nothing special about "factory" methods with respect to memory management. The same rules as with all methods apply. In this case, you have to assume that the returned object is autoreleased; you do not "own" it. The rules are:

    You "own" the object (you have to release it when using non-ARC) if it's method name starts with:

    Since these factory methods start with neither you don't own them and thus you do not release them yourself (unless you retain them first, of course).

    With ARC, the retaining/releasing/autoreleasing is something you don't think about that much any more. You care more about "weak" and "strong" references. So if you need these objects to stick around you need to assign them to strong properties or instance variables, otherwise they might get deallocated by the autoreleasing mechanism.