文章出處

ARC下:

Tools.h文件:

#import <Foundation/Foundation.h>

@interface Tools : NSObject<NSCopying, NSMutableCopying>

// 1.一般情況下,創建一個單例對象都有一個與之對應的類方法
// 2.一般情況下,創建單例對象的方法名稱都以share開頭,或以default開頭
+(instancetype)shareInstance;

@end
View Code

Tools.m文件:

#import "Tools.h"

@implementation Tools

// 一般都以share或default方法開頭的方法,都是創建單例的方法
+(instancetype)shareInstance{
    Tools *instance = [[self alloc] init];
    return instance;
}

static Tools *_instance = nil;// 定義一個全局的靜態變量

//對象創建的時候,調用alloc方法的時候,就會調用allocWithZone方法
//所以我們只需要在該方法中控制對象只被創建一次即可實現單例
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    /*
    // 以下代碼在多線程中,可能會出現問題
    // 單線程就采用以下的寫法
//    NSLog(@"%s",__func__);
//    // 由于所有的創建方法都會調用該方法,所以只需要在該方法中控制當前對象只創建一次即可
//    if (_instance == nil) {
//        NSLog(@"創建一個對象");
//        _instance = [[super allocWithZone:zone] init];
//    }
//    return _instance;
     */


    // 以下代碼在多線程中也能保證只執行一次
    // 多線程就采用以下的寫法
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}

//copyWithZone方法被調用,說明對象已經創建成功了,既然對象已經有了,說明_instance也就有值了。
- (id)copyWithZone:(nullable NSZone *)zone{
//    Tools *t = [[[self class] allocWithZone:zone] init];
//    return t;
    // 改成:
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone{
//    Tools *t = [[[self class] allocWithZone:zone] init];
//    return t;
    // 改成:
    return _instance;
}

@end
View Code

 

MRC下:

Tools.h文件:

#import <Foundation/Foundation.h>

@interface Tools : NSObject<NSCopying, NSMutableCopying>

+(instancetype)shareInstance;

@end
View Code

Tools.m文件:

#import "Tools.h"

@implementation Tools

+(instancetype)shareInstance{
    Tools *instance = [[Tools alloc] init];
    return instance;
}

static  Tools *_instance = nil;
// 調用alloc方法時,會調用allocWithZone方法
// 所以只要控制在這個方法中,只能創建一個唯一的對象,即可實現單例
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    /*
    if (_instance == nil) {
        _instance = [[super allocWithZone:zone] init];
        //不能通過 [[alloc] init]來創建,不然會發生死循環
    }
    return _instance;
     */

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}

// 實現copy中的方法
- (id)copyWithZone:(nullable NSZone *)zone{
    return _instance;
}

-(id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}

// 在MRC下,如果要控制只能有一個對象,則就不能讓這個對象釋放
-(oneway void)release{
    //這里什么都不做即可,即可保證整個過程中只有一份實例
}

-(instancetype)retain{
    return _instance;
}

-(NSUInteger)retainCount{
    //return 1;

    // 注意:為了方便程序員之間的溝通,一般情況下不會在單例中返回retainCount = 1,而是返回一個比較大的數值
    // 這樣做,就知道這個對象就只有一份實例
    return MAXFLOAT;
}

@end
View Code

main.m文件:

#import <Foundation/Foundation.h>
#import "Tools.h"

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

    Tools *tool = [Tools shareInstance];

    [tool release];

    return 0;
}
View Code

 

 

ps:自己慢慢琢磨。。。。。。

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()