繁体   English   中英

目标C中的单例(非ARC)

[英]Singleton in Objective C (Non-ARC)

我发现了如何在目标c(Non-ARC)中实现单例。

马特·加洛韦(Matt Galloway)的单身人士

// AppTools.h in my code

@interface AppTools : NSObject {

    NSString *className;
}

@property ( nonatomic, retain ) NSString *className;

+ ( id ) sharedInstance;

@end    // AppTools


// AppTools.m in my code

static AppTools *sharedAppToolsInstance = nil;

@implementation AppTools

@synthesize className;

- ( id ) init {

    self = [ super init ];
    if ( self ) {
        className = [ [ NSString alloc ] initWithString: @"AppTools" ];
    }
    return self;
}   // init

- ( void ) dealloc {

   // Should never be called, but just here for clarity really.
   [ className release ];
   [ super dealloc ];
}   // dealloc

+ ( id ) sharedInstance {

    @synchronized( self ) {
    if ( sharedAppToolsInstance == nil )
        sharedAppToolsInstance = [ [ super allocWithZone: NULL ] init ];
    }
    return sharedAppToolsInstance;
}   // sharedInstance

+ ( id ) allocWithZone: ( NSZone * )zone {

    return [ [ self sharedInstance ] retain ];
}   // allocWithZone:

- ( id ) copyWithZone: ( NSZone * )zone {

    return self;
}   // copyWithZone:

- ( id ) retain {

    return self;
}   // retain

- ( unsigned int ) retainCount {

    return UINT_MAX;    // denotes an object that cannot be released
}   // retainCount

- ( oneway void ) release {

    // never release
}   // release

- ( id ) autorelease {

    return self;
}   // autorelease

我想知道如何在sharedInstance方法中使用allocWithZone:。 在此,allocWithZone:方法的接收者为“ super”,“ super”为NSObject。 尽管返回值是NSObject实例,但它被替换为sharedInstance。

那么className的存储空间在哪里? 我不知道如何处理这部分代码。

预先感谢。

我认为您发布的代码很难用于创建单例。

在我的所有项目中,我都使用以下代码来使用单例。 它非常简单,线程安全并且可以完美运行:

+ (CustomClass *)shared
{
    static CustomClass *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[CustomClass alloc] init];
    });
    return singleton;
}

而且我相信您可以在ARC和非ARC项目中使用它。

更新:如注释中所述,它实际上是shared object而不是singleton因为可以创建更多特定类的实例。 但这已经足够接近了。

我认为,如果您不是在编写开源代码/库,而没有其他人会使用它,那么使用共享库并将它们视为单例可能会容易得多。

我使用与Nekto相同的代码,但singleton = [[CustomClass alloc] init]; 应该是singleton = [[self alloc] init];

想象一个子类CustomSubclass 如果你打电话

CustomSubclass *sharedObject = [CustomSubclass shared];

您将不会获得CustomSubclass而是CustomClass

您问“那么className的存储空间在哪里?”

大多数类本身并不实现allocallocWithZone ,而是依赖于从NSObject继承的实现。 NSObject实现分配原始调用类的对象。

因此,在您的示例AppTools确实覆盖了allocWithZone ,此实现通过对super的调用来调用NSObjectallocWithZone ,而NSObject的方法执行实际分配并返回AppTools类型的对象。

[注意:如果您想知道NSObject的实现如何知道要分配哪种对象,那么这很简单-调用继承的方法不会更改方法的self参数, alloc / allocWithZone是类方法,而self参数是类方法本身引用类对象(而不是类的实例对象)。]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM