pragma mark 單例ARC和MRC寫法 (Singleton)
pragma mark 概念
/**
1.單例模式概念
什么是單例模式: (Singleton)
- 單例模式 的意圖是 類的對(duì)象成為系統(tǒng)中唯一的實(shí)例,供一個(gè)訪問點(diǎn), 供客戶共享資源.
什么情況下 使用單例?
- 1. 類 只能有一個(gè)實(shí)例, 而且必須 從一個(gè)為人熟知的 訪問點(diǎn) 對(duì)其進(jìn)行訪問, 比如工廠方法
- 2. 這個(gè)唯一的實(shí)例 只能通過 子類化 進(jìn)行擴(kuò)展, 而且擴(kuò)展的對(duì)象 不會(huì)破環(huán)客戶端代碼
單例設(shè)置模式的要點(diǎn):
- 1. 某個(gè)類 只能 有一個(gè)實(shí)例
- 2. 他 必須 自行 創(chuàng)建這個(gè)對(duì)象
- 3. 必須 自行 想整個(gè)系統(tǒng) 提供這個(gè)實(shí)例;
- 4. 為了保證 實(shí)例的唯一性, 我們必須 將
- 5. 這個(gè)方法 必須是一個(gè)靜態(tài)類
2.簡(jiǎn)單的單例模式實(shí)現(xiàn)
重寫alloc 內(nèi)部的方法 allocWithZone
*/
pragma mark 代碼
#import <Foundation/Foundation.h>
#pragma mark 類
#import "Tools.h"
#pragma mark main函數(shù)
int main(int argc, const char * argv[])
{
#pragma mark 單例ARC和MRC寫法 (Singleton)
#pragma 1.ARC情況下
// 單例 就是 無論怎么 創(chuàng)建 都只能有 一個(gè)實(shí)例對(duì)象
// 如果地址 相同 就代表著 是同一個(gè)實(shí)例對(duì)象
Tools *t1 = [[Tools alloc]init]; // 內(nèi)部 會(huì)調(diào)用 allocWithZone
Tools *t2 = [Tools new]; // [ [alloc] init] // allocWithZone
Tools *t3 = [Tools shareInstance];
NSLog(@" %p %p %p",t1,t2,t3);
Tools *t4 = [t3 copy];
Tools *t5 = [t3 mutableCopy];;
NSLog(@"%p %p %p %p %p",t1,t2,t3,t4,t5);
NSLog(@"------1.end -------");
#pragma 2. MRC情況下
Tools *T1 = [[Tools alloc]init];
NSLog(@"T1 retainCount = %lu",[T1 retainCount]);
NSLog(@"T1 = %p",T1);
[T1 release];
Tools *T2 = [Tools shareInstance];
[T2 retain];
[T2 retain];
[T2 retain];
[T2 retain];
[T2 retain];
NSLog(@"T2 retainCount = %lu",[T2 retainCount]);
NSLog(@"T2 = %p",T2);
[T2 release];
return 0;
}
Tools.h //工具類
#import <Foundation/Foundation.h>
@interface Tools : NSObject <NSCopying,NSMutableCopying>
// 一般情況下 創(chuàng)建一個(gè) 單例對(duì)象 都有一個(gè) 與之對(duì)應(yīng)的類方法
// 一般情況下 用于 創(chuàng)建單例對(duì)象 的方法名稱 都以 share開頭, 或者以default開頭
+ (instancetype)shareInstance;
@end
Tools.m
#import "Tools.h"
@implementation Tools
+ (instancetype)shareInstance
{
Tools *instance = [[self alloc]init]; // // alloc 內(nèi)部會(huì)調(diào)用allocWithZone
return instance;
}
// 全局變量
static Tools * _instance = nil;
#pragma 0. 調(diào)用alloc內(nèi)部的方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
#pragma 1. ARC
/*
// 當(dāng)前代碼 在多線程中 可能會(huì)出現(xiàn)問題
NSLog(@"%s",__func__);
// 由于 所有的創(chuàng)建方法 都會(huì)調(diào)用該方法 , 所以只需要在 該方法中 控制當(dāng)前對(duì)象 只創(chuàng)建一次即可
if (_instance == nil) {
NSLog(@"創(chuàng)建了一個(gè)對(duì)象 %s",__func__);
_instance = [[super allocWithZone:zone]init];
}
return _instance;
*/
#pragma 2. 多線程中 處理
#warning 多線程的寫法
// 一下代碼 在 多線程中 也能保證 只執(zhí)行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:zone]init];
});
return _instance;
}
#pragma mark 2.copy
// copyWithZone 方法用很么調(diào)用 ? 對(duì)象
- (id)copyWithZone:(NSZone *)zone
{
#pragma 1
// Tools *t = [[self class] allocWithZone:zone];
// return t;
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
// Tools *t = [[self class] allocWithZone:zone];
// return t;
return _instance;
}
#pragma mark 3. ?? 如果是 ARC 使用單例 需要重寫一些方法
- (oneway void)release
{
// 為了保證整個(gè) 程序過程只什么都不做
}
- (instancetype)retain
{
return _instance;
}
- (NSUInteger)retainCount
{
// 注意: 為了方便 程序員之間溝通, 一般情況下不會(huì) 在單例中 返回 retainCount = 1;
// 而是返回 一個(gè)比較大的值
// return 1;
return MAXFLOAT;
}
@end
pragma mark 單例ARC和MRC寫法 (Singleton)
pragma mark 概念
/**
1.單例模式概念
什么是單例模式: (Singleton)
- 單例模式 的意圖是 類的對(duì)象成為系統(tǒng)中唯一的實(shí)例,供一個(gè)訪問點(diǎn), 供客戶共享資源.
什么情況下 使用單例?
- 1. 類 只能有一個(gè)實(shí)例, 而且必須 從一個(gè)為人熟知的 訪問點(diǎn) 對(duì)其進(jìn)行訪問, 比如工廠方法
- 2. 這個(gè)唯一的實(shí)例 只能通過 子類化 進(jìn)行擴(kuò)展, 而且擴(kuò)展的對(duì)象 不會(huì)破環(huán)客戶端代碼
單例設(shè)置模式的要點(diǎn):
- 1. 某個(gè)類 只能 有一個(gè)實(shí)例
- 2. 他 必須 自行 創(chuàng)建這個(gè)對(duì)象
- 3. 必須 自行 想整個(gè)系統(tǒng) 提供這個(gè)實(shí)例;
- 4. 為了保證 實(shí)例的唯一性, 我們必須 將
- 5. 這個(gè)方法 必須是一個(gè)靜態(tài)類
2.簡(jiǎn)單的單例模式實(shí)現(xiàn)
重寫alloc 內(nèi)部的方法 allocWithZone
*/
pragma mark 代碼
#import <Foundation/Foundation.h>
#pragma mark 類
#import "Tools.h"
#pragma mark main函數(shù)
int main(int argc, const char * argv[])
{
#pragma mark 單例ARC和MRC寫法 (Singleton)
#pragma 1.ARC情況下
// 單例 就是 無論怎么 創(chuàng)建 都只能有 一個(gè)實(shí)例對(duì)象
// 如果地址 相同 就代表著 是同一個(gè)實(shí)例對(duì)象
Tools *t1 = [[Tools alloc]init]; // 內(nèi)部 會(huì)調(diào)用 allocWithZone
Tools *t2 = [Tools new]; // [ [alloc] init] // allocWithZone
Tools *t3 = [Tools shareInstance];
NSLog(@" %p %p %p",t1,t2,t3);
Tools *t4 = [t3 copy];
Tools *t5 = [t3 mutableCopy];;
NSLog(@"%p %p %p %p %p",t1,t2,t3,t4,t5);
NSLog(@"------1.end -------");
#pragma 2. MRC情況下
Tools *T1 = [[Tools alloc]init];
NSLog(@"T1 retainCount = %lu",[T1 retainCount]);
NSLog(@"T1 = %p",T1);
[T1 release];
Tools *T2 = [Tools shareInstance];
[T2 retain];
[T2 retain];
[T2 retain];
[T2 retain];
[T2 retain];
NSLog(@"T2 retainCount = %lu",[T2 retainCount]);
NSLog(@"T2 = %p",T2);
[T2 release];
return 0;
}
Tools.h //工具類
#import <Foundation/Foundation.h>
@interface Tools : NSObject <NSCopying,NSMutableCopying>
// 一般情況下 創(chuàng)建一個(gè) 單例對(duì)象 都有一個(gè) 與之對(duì)應(yīng)的類方法
// 一般情況下 用于 創(chuàng)建單例對(duì)象 的方法名稱 都以 share開頭, 或者以default開頭
+ (instancetype)shareInstance;
@end
Tools.m
#import "Tools.h"
@implementation Tools
+ (instancetype)shareInstance
{
Tools *instance = [[self alloc]init]; // // alloc 內(nèi)部會(huì)調(diào)用allocWithZone
return instance;
}
// 全局變量
static Tools * _instance = nil;
#pragma 0. 調(diào)用alloc內(nèi)部的方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
#pragma 1. ARC
/*
// 當(dāng)前代碼 在多線程中 可能會(huì)出現(xiàn)問題
NSLog(@"%s",__func__);
// 由于 所有的創(chuàng)建方法 都會(huì)調(diào)用該方法 , 所以只需要在 該方法中 控制當(dāng)前對(duì)象 只創(chuàng)建一次即可
if (_instance == nil) {
NSLog(@"創(chuàng)建了一個(gè)對(duì)象 %s",__func__);
_instance = [[super allocWithZone:zone]init];
}
return _instance;
*/
#pragma 2. 多線程中 處理
#warning 多線程的寫法
// 一下代碼 在 多線程中 也能保證 只執(zhí)行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:zone]init];
});
return _instance;
}
#pragma mark 2.copy
// copyWithZone 方法用很么調(diào)用 ? 對(duì)象
- (id)copyWithZone:(NSZone *)zone
{
#pragma 1
// Tools *t = [[self class] allocWithZone:zone];
// return t;
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
// Tools *t = [[self class] allocWithZone:zone];
// return t;
return _instance;
}
#pragma mark 3. ?? 如果是 ARC 使用單例 需要重寫一些方法
- (oneway void)release
{
// 為了保證整個(gè) 程序過程只什么都不做
}
- (instancetype)retain
{
return _instance;
}
- (NSUInteger)retainCount
{
// 注意: 為了方便 程序員之間溝通, 一般情況下不會(huì) 在單例中 返回 retainCount = 1;
// 而是返回 一個(gè)比較大的值
// return 1;
return MAXFLOAT;
}
@end