单例或类方法 [英] Singleton or Class methods

查看:91
本文介绍了单例或类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读对有关单例的> 的回答后在目标C中,似乎每个解决方案都在实例访问器中的线程方面进行了一些折衷.即

After reading the responses to a question about singletons in Objective C it appears that each solution makes some tradeoff in regards to threading in the instance accessor. i.e.

@synchronized(self)
{
    if (sharedInstance == nil)
            sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;

这本质上是单线程对单例的访问,并且如果它是某个操作中经常使用的东西,则可能会导致不必要地争用线程.

This essentially single-threads access to the singleton, and if it's something that's used frequently in an operation, seems like something that could cause threads to unnecessarily contend.

简单地将类对象用作单例实例并通过类方法公开功能(即

What's the downside to simply using the class object as the singleton instance, and exposing functionality via class methods, i.e.

@interface MySingleton : NSObject {
}

+ (void)doSomething;
@end

@implementation MySingleton    
+ (void)initialize {
   //do some setup if necessary
}

+ (void)doSomething {
    //do something
}
@end

这样,我们避免每次希望引用单例对象时都要进行lock + check,并且还可以避免将其存储在本地或方法ivar中的情况.

In this way we avoid doing the lock + check every time we want to reference the singleton object and we can also eliminate having to store it in a local or method ivar.

这种方法还使运行时可以保证在任何给定时间系统中仅存在一个实例(Class对象).

This approach also lets the runtime guarantee that only one instance (the Class object) exists in the system at any given time.

编辑

这里不仅有线程,还有传统的单例代码,通常您可以这样编写代码:

There's more here than just threading, with a traditional singleton you usually write code like this:

MySingleton *instance = [MySingleton getSharedInstance];
NSObject *someResult = [instance getResult];
//or
if (instance.someProperty) {
  //do something
}

但是,如果您的单身人士是一个类实例,那么您基本上就一直不需要调用getSharedInstance.考虑以下代码:

However if your singleton is a class instance, you essentially eliminate the need call getSharedInstance all the time. Consider this code:

NSObject *someResult = [MySingleton getResult];
//or
if ([MySingleton someProperty]) {
  //do something
}

我听说您必须将数据存储在文件本地静态变量或全局变量(yuck)中.但这实际上与传统的单例并没有什么不同,除了失去了Objective-C 2.0属性(相反,您必须使用传统的访问器方法).

I hear the point that you have to store your data in file local static variables, or in global variables (yuck). But it's really not all that different from a traditional singleton with the exception that you lose Objective-C 2.0 properties (instead you have to use traditional accessor methods).

对我来说,这是一个关键的权衡,这似乎是一次胜利.在传统的单例中,如果您确实想解决问题,则最终会覆盖-copyWithZone,+ allocWithZone,-retain,-retainCount,-release和-autorelease.

Here's one key tradeoff for me that seems like a win. In a traditional singleton you end up overriding -copyWithZone, +allocWithZone, -retain, -retainCount, -release and -autorelease if you really want to get things right.

每次您要编写一个简单的Singleton对象(似乎非常有用)时,这似乎需要做很多工作.那么,为什么不简单地将其替换为:

This seems like an awful lot of work to do every time you want to write a simple Singleton object (they happen to be pretty useful). So why not simply just replace it with this:

@implementation MySingleton
+ (void)initialize {
    //do your setup
}

- (id)init {
    NSAssert(NO, @"You should read the documentation on singletons.");
}
@end

就代码而言,它要轻得多,除非您的消费者真的很偷偷摸摸,否则他们将永远不会创建两个实例.

It's a lot lighter in terms of code, and unless your consumers are really sneaky they won't ever create two instances.

已达到目的 我的问题确实是这样:

Get to the point already My question is really this:

使用Class对象作为单例实例是否有缺点?

Is there any drawback to using the Class object as the instance of your singleton?

似乎您可以在线程安全性,内存效率等方面采取所有相同的步骤,而不必记住要重写这么多的方法和访问器,或者用实例检查乱扔代码.

It seems like you can take all the same steps in terms of threadsafety, memory efficiency etc. without having to remember to override so many methods and accessors or litter your code with instance checks.

推荐答案

这是我关于Stack Overflow的第一篇文章...(所以要做好愚蠢的准备)

This is my first post on Stack Overflow... (so prepare for stupidity)

我认为有一种混合解决方案可能会有用.

I think there is a hybrid solution that might be useful.

我想从单例类中设置和获取(全局)值,而无需调用"getSharedInstance".我希望代码看起来像这样……

I want to set and get (global) values out of a singleton class without having calling "getSharedInstance". I'd want the code to look like this...

frameRate = Singleton.frameRate;
Singleton.frameRate = 42;

要实现这一点,我们需要存储在单例中的每个变量都有一个getter和setter类方法.然后,类方法转到实例以将数据存储在ivar中.主程序不能直接访问该实例.

To achieve this, each variable we need to store in the singleton has a getter and setter class method. The class method then goes to an instance to store the data in an ivar. The instance isn't directly accessed by the main program.

吸气剂看起来像这样:

+ (int) frameRate
{
    return [[Singleton instance] ivarFrameRate];
}

(丑陋的)实例调用隐藏在类代码中.

The (ugly) instance call is hidden inside the class code.

通过在此处调用实例方法,类方法将在首次使用时自动实例化一个对象.实例化单例后,实例将按常规存储Ivar.在这里,我以"ivar"为前缀使ivar明确.

By calling the instance method here, the class method will automatically instantiate an object when first used. Once the singleton is instantiated, the instance stores ivars conventionally. Here, I am prefixing with "ivar" make the ivar explicit.

@property  int ivarFrameRate;

@synthesize ivarFrameRate;

这会自动创建常规的getter(和setter)方法来访问ivar.

This automatically creates conventional getter (and setter) methods to access the ivar.

(编辑-这是一个完整的示例)

(edit - here is a complete example)

//  Singleton.h
#import <Foundation/Foundation.h>
@interface Singleton : NSObject
{
float ivarFrameRate
}

@property  float ivarFrameRate;

- (id) init;
+ (Singleton *) instance;
+ (float) frameRate;
+ (void) setFrameRate:(float)fr;
@end

//  Singleton.m
#import "Singleton.h"
@implementation Singleton
@synthesize ivarFrameRate;

static Singleton* gInstance = NULL;

+ (Singleton*)instance
{
    @synchronized(self)
    {
        if (gInstance == NULL)
        gInstance = [[self alloc] init];
    }
    return(gInstance);
}


- (id)init
{
    self = [super init];
    return self;
}

+ (float) frameRate
{
    return [[Singleton instance] ivarFrameRate];
}

+ (void) setFrameRate:(float)fr;
{
    [[Singleton instance] setIvarFrameRate:fr];
}

这篇关于单例或类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆