iOS OC C

单例

920 发布: 2015/11/10 08:34 本文总阅读量

20241210补充:swift单例

1.快捷简单

public static let shared: LyNetwork = .init()

private init() {
    // 私有初始化方法,防止外部直接初始化
}

2.冗余

static let shared: LyNetwork = {
    // 先定义instance为可选类型
    var instance: LyNetwork?
    let queue = DispatchQueue(label: "com.lynetwork.singleton")
    queue.sync {
        // 在闭包内安全地初始化instance
        instance = LyNetwork()
    }
    // 使用可选绑定确保instance有值后再返回,如果没有值会触发运行时错误,不过在正常逻辑下不会出现这种情况,因为闭包内会进行初始化
    guard let unwrappedInstance = instance else {
        fatalError("Singleton instance not initialized")
    }
    return unwrappedInstance
}()
private init() {
    // 私有初始化方法,防止外部直接初始化
    /* swift 中不允许使用 dispatch_once
    var onceToken: dispatch_once_t = 0
    var instance: LyNetwork?
    dispatch_once(&onceToken, {
        instance = LyNetwork()
    })
    */
}
  • 稍复杂的实现:使用了一个闭包和调度队列来初始化单例实例,代码相对复杂。
  • 理论上的线程控制:使用 DispatchQueue 进行同步操作,目的是确保单例实例的初始化是线程安全的。不过在 Swift 中,静态常量本身已经保证了线程安全,这里的调度队列使用略显冗余。
  • 延迟初始化的错觉:虽然代码看起来像是在控制初始化时机,但由于整个闭包在类加载时就会执行,实际上仍然是立即初始化,并非真正的延迟初始化。 错误处理:使用 guard let 进行可选绑定,如果 instance 为 nil 会触发 fatalError,不过在正常情况下这种情况不会发生。

AI总结

  • 方式二这种实现方式在 Swift 中并不常见,因为它没有充分利用 Swift 语言本身的特性。如果是从 Objective - C 迁移过来的代码,可能会保留这种传统的线程安全初始化思路。但在纯 Swift 项目中,建议采用更简洁的方式。

实例0

.m

static YBRechargeType *chargeManeger = nil;

+(instancetype)chargeManeger {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        chargeManeger = [[super allocWithZone:NULL]init];
    });
    return chargeManeger;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone {
    return [self chargeManeger];
}

实例1

UserContext.h头文件:

#import     

@interface UserContext : NSObject <NSCopying>

@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *email;        

//单例 类方法

+(id)shareUserContext;

@end
UserContext.m实现文件:       

#import "UserContext.h"

//单例对象

static UserContext *sigletonInstance=nil;

@implementation UserContext

//生成单例对象

+(id)shareUserContext{

     @synchronized(self){

      if (sigletonInstance==nil) {

                    sigletonInstance=[[[self class] alloc]init];

                }

            }

            return sigletonInstance;

        }

//下面的方法确保只有一个实例对象

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

      if (sigletonInstance==nil) {

                sigletonInstance=[super allocWithZone:zone];

            }

            return  sigletonInstance;

        }

-(id)copyWithZone: (NSZone *)zone

{

    return  sigletonInstance;

}

-(id)retain

{

    return  sigletonInstance;

}

-(oneway void)release

{

            

}

-(id)autorelease

{

    return  sigletonInstance;

}

-(NSUInteger)retainCount

{

   return UINT_MAX;

}

@end
main.m测试代码:

#import

#import "UserContext.h"

int main(int argc, const char * argv[]) {

     @autoreleasepool {

           UserContext *userContext1=[UserContext shareUserContext];

           UserContext *userContext2=[UserContext shareUserContext];

           UserContext *userContext3=[[UserContext alloc]init];

           UserContext *userContext4=[userContext3 copy];

                [userContext1 release];

                [userContext1 release];

                [userContext1 release];

                [userContext1 release];

                NSLog(@" ");

            }
         return 0;
     }