除了语法之外,是不是有任何理由通过类方法实例化对象?
Posted
技术标签:
【中文标题】除了语法之外,是不是有任何理由通过类方法实例化对象?【英文标题】:Is there any reason to instantiate an object through a class method, other than syntax?除了语法之外,是否有任何理由通过类方法实例化对象? 【发布时间】:2015-09-17 19:49:41 【问题描述】:我一直在修复一个错误,并在一些非常旧的代码中结束,我发现了一些我不完全理解的东西
我们目前正在像这样初始化一个对象:
MyViewController* myViewController = [MyViewController viewControllerForDocument:(MyDocument*)doc];
而+viewControllerForDocument
是一个类方法:
+ (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;
我知道这看起来很有趣,但我的问题是为什么开发人员会选择通过类方法来实例化对象——而不是仅仅编写自定义实例初始化程序?类方法的实现无论如何都包含实例初始化器-initWithNibName
。
之所以现在出现这个问题,是因为[result view]
加载了调用-awakeFromNib
的笔尖。
-awakeFromNib
需要注意myDocument
;但由于初始化程序是一个类方法,我无法将myDocument
存储到实例属性中。
我也不能在 [result view]
调用之前移动 [result.myController setDocument:myDocument];
,因为 myController 是通过 nib 加载的。
无论如何,这整件事让我觉得很臭,而且它是由一位早已不在的员工于 2010 年撰写的,这让我持怀疑态度。
任何人都可以阐明以这种方式实现事物的可能动机吗?我也不认为通过 nib 通过访问 view
手动加载对象也不好,但我真的没有任何理由说它不好
【问题讨论】:
类似are found throughout Cocoa的构造方法。这是完全有效的。 哇,2010 年“被一些相当古老的代码所包围”?我刚开始编写代码库,最初是在 1980 年代开始的,最后一次工作是在 2000 年。 "-awakeFromNib
需要注意 myDocument
;但由于初始化程序是类方法,我无法将 myDocument
存储到实例属性中。"文档设置在下一行——你不能因为某种原因重新排序吗?
你是对的——我一开始很困惑,所以我的问题肯定是错误的。它开始是因为我想将其存储为self.myDocument
-- 而我只需要改为result.myDocument
。事后看来很明显
另外请原谅我的新手,我大约一年前才开始使用 Objective-C 和 Cocoa。还在学习 :) 感谢 cmets 伙计们
【参考方案1】:
这与NSString
类方法的以下内容有何特别不同:
+ (instancetype)stringWithUTF8String:(const char *)bytes
两者都是类方法,有时称为便利初始化器。
在 ARC 之前它们更有用,因为它们避免了 alloc
init
autorelease
模式:
MyClass *inst = [[[MyClass aloc] init] autorelease];
【讨论】:
仍然使用它们的一个原因是当类缓存实例时;另一个是类簇。这比必须销毁init...
中无用的传入实例要方便一些。以上是关于除了语法之外,是不是有任何理由通过类方法实例化对象?的主要内容,如果未能解决你的问题,请参考以下文章