块中的 [self new] 会产生强引用循环吗?

Does [self new] in a block creates strong reference cycle?

我正在创建单例,如下所示:

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

我知道块中的代码将被执行一次并且self在那一点将是nil,所以[self new]将等于[MyType new]。但是后来我在考虑情况,当我在一个不是用于单例目的并且可以多次调用的块中调用 [self new] 时。

[self new] 会像 [MyType new] 一样还是块会捕获 self?使用 [self new] 创建 MyType 的新实例是否正确?使用 [self new] 而不是 [MyType new] 有什么好处?

没有。没有"cycle"。该块捕获对 class 对象的强引用(这是 self 指向此处的内容,因为它是 class 方法)。 class 对象不包含对该块的任何引用。

是的,self被块捕获,但是块没有被self捕获,所以没有释放周期。无论如何,由于 self 指向 MyType 的 class 对象,并且因为 class 对象永远不会被释放,所以在这种特定情况下你不应该太担心保留周期。

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

如其他答案所述,这不是保留循环。但是,请记住 self 指向 class 对象并且 class 对象不是 ARC 的对象:它们具有永恒的生命周期。

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]?

在 class 的实现中,您应该几乎总是 使用 self 而不是 MyType。 (但是您的代码是由于静态变量而没有这样做的优势的罕见示例之一。)

这样做的原因是,代码可以被 subclasses 使用。如果将具体类型放入代码中,则必须覆盖每个创建方法,这会导致代码过多并触发 broken base class 问题。

示例:

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

@interfac Subclass : BaseClass
…
@end

这是坏的,因为...

id instance = [Subclass new…];

… 将创建子class.

的一个实例

你必须覆盖new…,还有一个问题:

@implementation Subclass
+(instancetype)new…
{
  /* Subclass *instance = [super new]; Does NOT work*/
  … Complete re-implementation of +new… (BaseClass)
}