除了语法之外,是否有任何理由通过 class 方法实例化对象?

Is there any reason to instantiate an object through a class method, other than syntax?

我一直在修复一个错误并在一些相当旧的代码中结束,我发现了一些我不完全理解的东西

我们目前正在初始化这样一个对象:

MyViewController* myViewController = [MyViewController viewControllerForDocument:(MyDocument*)doc];

+viewControllerForDocument是一个class方法:

+ (instancetype)viewControllerForDocument:(MyDocument*)myDocument
{
   MyViewController* result = nil;
   result = [[MyViewController alloc] initWithNibName:@"MyViewController"
                                                        bundle:[NSBundle mainBundle]];

   if ( result )
   {
      [result view];
      [result.myController setDocument:myDocument];
      [myDocument setController:result.myController];
   }
   return result;
}

我知道这看起来很有趣,但我的问题是为什么开发人员会选择通过 class 方法实例化对象,而不是只编写自定义实例初始化程序? class 方法的实现无论如何都包含实例初始化程序 -initWithNibName

之所以现在成为一个问题,是因为 [result view] 加载了调用 -awakeFromNib 的笔尖。

-awakeFromNib需注意myDocument;但是因为初始化器是一个 class 方法,所以我无法将 myDocument 存储到实例 属性.

我也无法在 [result view] 调用之前移动 [result.myController setDocument:myDocument];,因为 myController 是通过 nib 加载的。

无论如何,这整件事让我很反感,而且它是由一位早已离开的员工于 2010 年编写的这一事实让我持怀疑态度。

任何人都可以阐明以这种方式实施事情的可能动机吗?我也不认为通过访问 view 通过 nib 手动加载对象是好的,但我真的没有任何理由说它不好

这与以下 NSString class 方法有何特别不同:

+ (instancetype)stringWithUTF8String:(const char *)bytes

两者都是 class 方法,有时称为便利初始化器。

它们在 ARC 之前更有用,因为它们避免了 alloc init autorelease 模式:

MyClass *inst = [[[MyClass aloc] init] autorelease];