![]() |
1
207
另一种选择是使用
所以你可以做类似的事情:
|
![]() |
2
95
|
![]() |
3
59
根据我下面的其他答案,我认为你应该这样做:
|
![]() |
4
58
自从 Kendall posted 一个试图避免锁定成本的线程安全单例,我想我也会扔掉一个:
好吧,让我解释一下这是如何工作的:
|
![]() |
5
14
静态myclass*sharedinst=nil; +(ID)共享状态 { @同步(自我){ 如果(sharedinst==nil){ /*在init中设置sharedinst*/ [[self alloc]init]; } } 返回sharedinst; } -(ID)初始化 { 如果(分享!= nIL){ [N异常提升:N异常 格式:@“[%@%@]无法调用;请改为使用+[%@%@”], nsstringfromclass([self class]),nsstringfromselector(_cmd), nsStringFromClass([自类]), nsstringfromselector(@selector(sharedInstance)“]; }else if(self=[super init])。{ sharedinst=自己; /*这里有什么具体的课程*/ } 返回sharedinst; } /*这些可能对 一个GC应用程序。保持单身 作为一个真正的单身汉 非CG应用程序 */ -(nsuinteger)重新计数 { 返回nsintegermax; } -(单向无效)释放 { } -(ID)保留 { 返回sharedinst; } -(ID)自动释放 { 返回sharedinst; } |
![]() |
6
12
编辑:此实现与ARC一起废弃。请看一下 How do I implement an Objective-C singleton that is compatible with ARC? 以便正确实施。 我在其他答案中读到的初始化的所有实现都有一个共同的错误。
Apple文档建议您检查初始化块中的类类型。因为子类在默认情况下调用初始化。存在一种不明显的情况,子类可以通过kvo间接创建。如果在另一个类中添加以下行:
Objective-C将隐式创建mysingletonclass的子类,从而导致第二次触发
您可能认为应该隐式检查init块中的重复初始化,例如:
但是你会射自己的脚;或者更糟的是,给另一个开发者机会射自己的脚。
tl;dr,这是我的实现
(用我们自己的断言宏替换zassert;或者只替换nsassert。) |
![]() |
7
10
关于单子宏代码的一个透彻的解释在博客cocoa with love上。 http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html . |
![]() |
8
9
我在sharedInstance上有一个有趣的变体,它是线程安全的,但在初始化后不锁定。我还不确定是否有足够的理由按要求修改最上面的答案,但我将其提交以供进一步讨论:
|
![]() |
9
6
简短的回答:太棒了。 长话短说:比如……
请务必阅读 dispatch/once.h header 了解发生了什么。在这种情况下,标题注释比文档或手册页更适用。 |
![]() |
10
5
我已经将singleton回滚到一个类中,以便其他类可以继承singleton属性。 单身:H:
单身汉:
下面是一些类的例子,你想成为单身汉。
单例类的唯一限制是它是nsObject子类。但大多数时候,我在代码中使用单例,它们实际上是nsObject子类,所以这个类真的让我的生活更轻松,代码更干净。 |
![]() |
11
2
这也适用于非垃圾收集环境。
|
![]() |
12
2
这是不是应该是threadsafe,避免在第一次呼叫后进行昂贵的锁定?
|
![]() |
13
2
Here's a macro 我把它们放在一起: http://github.com/cjhanson/Objective-C-Optimized-Singleton 它是建立在 the work here by Matt Gallagher 但是将实现更改为使用 method swizzling as described here by Dave MacLachlan of Google . 我欢迎评论/贡献。 |
![]() |
14
2
怎么样
所以您可以避免初始化后的同步开销? |
![]() |
15
2
要深入讨论Objective-C中的单例模式,请查看以下内容: |
![]() |
16
1
|
![]() |
17
0
您不想自己同步…因为自我对象还不存在!最后锁定一个临时ID值。您希望确保没有其他人可以运行类方法(sharedInstance、alloc、allocWithZone等),因此需要在类对象上进行同步:
|
![]() |
18
0
只是想把这个留在这里,这样我就不会丢了。它的优势在于它可以在InterfaceBuilder中使用,这是一个巨大的优势。 This is taken from another question that I asked :
|
![]() |
19
0
|
![]() |
20
0
我知道关于这个“问题”有很多评论,但是我没有看到很多人建议使用宏来定义单例。这是一种常见的模式,宏大大简化了单例。 下面是我根据我看到的几个objc实现编写的宏。
使用实例:
为什么界面宏几乎为空?头文件和代码文件之间的代码一致性;可维护性,以防您想添加更多的自动方法或更改它。 我正在使用初始化方法创建singleton,这是这里最流行的答案(在编写时)中使用的方法。 |
![]() |
21
0
使用目标C类方法,我们可以避免使用通常的单例模式,从:
到:
通过将类包装在另一个类中 类方法 ,这样就不会意外地创建重复实例,因为我们不会创建任何实例! 我写了一个更详细的博客 here :) |
![]() |
22
0
要扩展@robbie hanson的示例…
|
![]() |
23
0
我的方法很简单:
如果singleton已经初始化,则不会输入锁块。第二个检查如果(!初始化)是为了确保在当前线程获取锁时它还没有初始化。 |
![]() |
24
0
我没有通读所有的解决方案,所以如果这段代码是多余的,请原谅。 在我看来,这是最安全的线程实现。
|
![]() |
25
-4
我通常使用与本·霍夫斯坦的答案大致相似的代码(我也从维基百科中得到)。我使用它是因为克里斯·汉森在他的评论中陈述的原因。 但是,有时我需要把一个单件放到一个笔尖上,在这种情况下,我使用以下方法:
我离开执行
|
![]() |
26
-5
接受的答案,尽管它是编译的,是不正确的。
根据苹果文件: …您可以采用类似的方法,使用类对象而不是自身来同步关联类的类方法。 即使使用“自我工作”,它也不应该,这对我来说就像是一个复制粘贴错误。 类工厂方法的正确实现是:
|
![]() |
S qasem · Android内存性能 6 年前 |
![]() |
R83nLK82 · 在单例设计模式上引发IOException 6 年前 |
![]() |
hal · 两个课程有什么区别?他们的工作方式不同吗? 6 年前 |
![]() |
Jaquarh · 如何在不使用DI的情况下实例化父类 6 年前 |
|
Deepanshu · 基于PHP的Web应用程序中的单例对象状态 6 年前 |
![]() |
dicle · 视图控制器中的依赖项注入 6 年前 |
![]() |
Kozuki · 如何在生产代码中考虑单例? 7 年前 |