0

I am creating singleton like shown below:

static MyType* shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    shared = [self new];
});
return shared;

I know that the code in the block will be executed once and self will be nil at that point, so [self new] will be equal to [MyType new]. But then I was thinking about situation, when I call [self new] in a block that is not for singleton purposes and can be called more than once.

Will [self new] act like [MyType new] or a block will capture self? Is it a right way to create new instance of MyType using [self new]? What are benefits of using [self new] instead of [MyType new]?

WantToKnow
  • 1,767
  • 2
  • 12
  • 18
  • when you call self new] outside of your singleton init method, you are creating a new instance. There is no point in creating singleton if you want to call [self new] outside of it. – Teja Nandamuri Aug 26 '16 at 14:09
  • @TejaNandamuri the question is "Does block, that use [self new] in it will capture self?", sorry if it is not clarified in question. – WantToKnow Aug 26 '16 at 14:45
  • No, strong reference will not be created unless you call that block using self. And you should use weakself if you want to call the self in a block. It is best expained in here http://stackoverflow.com/questions/20030873/always-pass-weak-reference-of-self-into-block-in-arc – Teja Nandamuri Aug 26 '16 at 14:50

3 Answers3

1

No. There is no "cycle". The block captures a strong reference to the class object (which is what self points to here as it is a class method). The class object does not hold any reference to the block.

newacct
  • 119,665
  • 29
  • 163
  • 224
0

Yes, self is captured by the block, however the block is not captured by self, so no release cycle. Anyhow, since self points to the class object for MyType, and because class objects are never deallocated, you should not worry much about retain cycles in this particular scenario.

Cristik
  • 30,989
  • 25
  • 91
  • 127
0

Will [self new] act like [MyType new] or a block will capture self?

As mentioned by the other answers, this is no retain cycle. However, keep in mind that self points to the class object and class objects are not object of ARC: They have an eternal life time.

Is it a right way to create new instance of MyType using [self new]?

It is the better way. See below.

What are benefits of using [self new] instead of [MyType new]?

Inside the implementation of the class you should almost always use self instead of MyType. (But your code is one of the rare examples for having no advantage of doing so because of the static variable.)

The reason for this is, that code can be used by subclasses. If you put the concrete type in your code, every creation method has to be overwritten, which can lead to much code and triggers the broken base class problem.

Example:

@implementation BaseClass
+ (instancetype)new…
{
  BaseClass *instance = [BaseClass new];
  …
}
@end

@interfac Subclass : BaseClass
…
@end

This is broken, because …

id instance = [Subclass new…];

… would create an instance of the subclass.

You have to overwrite new…, what has an additional problem:

@implementation Subclass
+(instancetype)new…
{
  /* Subclass *instance = [super new]; Does NOT work*/
  … Complete re-implementation of +new… (BaseClass)
}
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50