1

I'm having trouble understanding the use of [[self alloc] init] when writing factory methods. I understand that factory methods are convenience methods to create instances of a class, and that they do the alloc, init, and autorelease for you. I can see how this is formed, for example in the declaration of an NSArray property with the factory method arrayWithArray:, or array, etc. called on it to set it up. I can obviously see how this is different to an outright (explicit) call to alloc and init.

My issue with this is that I don't understand factory methods at a deeper level. I came across an explanation online that said instead of calling alloc and init explicitly, a class factory method could be used to basically encapsulate something like this:

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

But how do instancetype and [self alloc] effectively allow for subclasses to make use of the class factory method?

jscs
  • 63,694
  • 13
  • 151
  • 195
cheznead
  • 2,589
  • 7
  • 29
  • 50
  • 2
    I'm not sure exactly what you're asking. Does [Class methods which create new instances](http://stackoverflow.com/q/5987969) explain anything for you? – jscs Feb 24 '15 at 19:37
  • 1
    this approach has no issues with subclasses because `self` if resolved dynamically at runtime and will "point" to the "active class". `NSArray`, `NSNumber`, `NSString` are special cases called class clusters ([official doc](https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html)) – tkanzakic Feb 24 '15 at 19:45
  • @Josh: Yep, that is really helpful. I'm just done reading this page and found it very useful: http://qualitycoding.org/factory-method/ – cheznead Feb 24 '15 at 20:39
  • Just one question. Say you do an explicit alloc - when using ARC, do you need to worry about autorelease anymore? – cheznead Feb 24 '15 at 20:40
  • I meant manual release..sorry – cheznead Feb 24 '15 at 20:48
  • @shinnyWhack: Nope, not necessary to call `autorelease` when using ARC. (ARC will insert that call for you.) – mipadi Feb 24 '15 at 21:40

1 Answers1

5
  1. instancetype is a keyword that says "the return type of this method is the type of the class that this method was called on" (or a subclass). So, if you call [Baseclass createWithString:], the return type is Baseclass *. However, let's say you create a subclass that does not override this method. If you call [Subclass createWithString:], the return type is Subclass * (not Baseclass *).

  2. When a class receives a message, self points to the Class object. So when calling [Baseclass createWithString:], self will point to the Baseclass object. However, when calling [Subclass createWithString:], self will point to Subclass instead, so if Subclass defines its own alloc or initWithString: methods (that is, it overrides them) its versions will be called instead.

mipadi
  • 398,885
  • 90
  • 523
  • 479