iOS開発マルチスレッド編—一例モード(ARC)整理小材料


iOS開発マルチスレッド編-一例モード(ARC)
一、簡単な説明:
設計モデル:長年のソフトウェア開発、総括した経験、方法とツール
JAvaには23種類の設計モードがあり、iosで最もよく使われるのは単例モードとエージェントモードです.
 
二、単例モード説明
(1)単一例モードの役割:プログラムの実行過程において、1つのクラスに1つのインスタンスしかなく、そのインスタンスが外部にアクセスしやすく、それによってインスタンスの個数を容易に制御し、システム資源を節約することができる.
(2)単一モードの使用例:アプリケーション全体でリソースを共有し(このリソースは初期化を1回作成するだけ)、このクラスで作成すべきオブジェクトは永遠に1つしかありません.
(3)一例モードではARCMRC環境での書き方が異なり、異なるコードを2セット作成する必要がある
マクロでARC環境かどうかを判断できます
#if __has_feature(objc_arc)
 // ARC
#else
// MRC
#endif

(4)ARCにおいて、一例モードの実現構想
はい.mにグローバルなstaticのインスタンスstatic idを保持するinstance; 
1)allocWithZoneを書き換える:ここで唯一のインスタンスを作成する方法(スレッドセキュリティに注意)
1 + (id)allocWithZone:(struct _NSZone *)zone
2 {    @synchronized(self) {
3         if (!_instance) {
4             _instance = [super allocWithZone:zone];
5         }
6     }
7     return _instance;
8 } 

2)外部から唯一アクセスできるクラスメソッドを提供する.
1 + (instancetype)sharedSoundTool
2 {
3     @synchronized(self) {
4         if (!_instance) {
5             _instance = [[self alloc] init];
6         }
7     }
8     return _instance;
9 }

3)copyWithZoneを実現する:方法
1 + (id)copyWithZone:(struct _NSZone *)zone
2 {
3     return _instance;
4 }

 
(5)非ARC(MRC)において、一例のモードの実現(ARCよりいくつかのステップが多い)
メモリ管理方法の実装
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (oneway void)release {}
- (id)autorelease { return self; }
  
三、一例モード(ARC)
1.説明
allocWithzone:メソッドを書き換え、メモリ割り当てを制御します.alloc内部でメソッドが呼び出されるため、allocWithzone:メソッドが呼び出されるたびに、システムは新しいメモリ領域を作成します.
allocメソッド:メモリは常に1回のみ割り当てられます
Initメソッドでは、すべてのMP 3データが1回しかロードされないことを保証します.
 
 2.コードの例
サブNSObjectクラスを継承するオーディオツールクラスを作成します.
このクラスでは、次のコードが実装されます.
 1 //
 2 //  YYAudioTool.m
 3 //  06-    1
 4 //
 5 //  Created by apple on 14-6-25.
 6 //  Copyright (c) 2014  itcase. All rights reserved.
 7 //
 8 
 9 #import "YYAudioTool.h"
10 @interface YYAudioTool ()
11 //    mp3  
12 @property(nonatomic,strong)NSMutableDictionary *muscis;
13 @end
14 @implementation YYAudioTool
15 //    
16 -(id)init
17 {
18     if (self=[super init]) {
19         //         
20         //....
21 //        self.muscis=[NSMutableDictionary dictionary];
22 //        self.muscis[@"1.mp3"]=1mp3  ;
23 //        self.muscis[@"2.mp3"]=2mp3  ;
24     }
25     return self;
26 }
27 
28 //       
29 +(id)alloc
30 {
31     NSLog(@"alloc----");
32     return [super alloc];
33 }
34 
35 //      ,    allocWithzone:  ,              
36 +(id)allocWithZone:(struct _NSZone *)zone
37 {
38     NSLog(@"allocWithZone---");
39     return [super allocWithZone:zone];
40 }
41 
42 
43 
44 @end

メインコントローラで、ツールクラスオブジェクトを作成します.
 1 //
 2 //  YYViewController.m
 3 //  06-    1
 4 //
 5 //  Created by apple on 14-6-25.
 6 //  Copyright (c) 2014  itcase. All rights reserved.
 7 //
 8 
 9 #import "YYViewController.h"
10 #import "YYAudioTool.h"
11 
12 @interface YYViewController ()
13 
14 @end
15 
16 @implementation YYViewController
17 
18 - (void)viewDidLoad
19 {
20     [super viewDidLoad];
21     YYAudioTool *tool1=[[YYAudioTool alloc]init];
22     YYAudioTool *tool2=[[YYAudioTool alloc]init];
23     YYAudioTool *tool3=[[YYAudioTool alloc]init];
24     YYAudioTool *tool4=[[YYAudioTool alloc]init];
25     NSLog(@"%p--%p--%p--%p",tool1,tool2,tool3,tool4);
26 }
27 
28 @end

印刷結果:
説明:allocの内部では、より下位レベルのメソッドallocWithZoneメソッドがメモリ領域を割り当て、上のコードは4つの異なるオブジェクトを作成します. 
3.単例モード:設計構想
(1)オブジェクトを作成するために常に1つのメモリのみを割り当てる
(2)内部で一意の変数を返すクラスメソッドを提供する
(3)initメソッドも一度だけ初期化することが望ましい
コードの例:
サブNSObjectクラスを継承するオーディオツールクラスを作成します.
このクラスでは、次のコードを設計の考え方に従って実現します.
YYAudioTool.mファイル
 1 //
 2 //  YYAudioTool.m
 3 //  06-    1
 4 //
 5 //  Created by apple on 14-6-25.
 6 //  Copyright (c) 2014  itcase. All rights reserved.
 7 //
 8 
 9 #import "YYAudioTool.h"
10 @interface YYAudioTool ()
11 //    mp3  
12 @property(nonatomic,strong)NSMutableDictionary *muscis;
13 @end
14 
15 @implementation YYAudioTool
16 //      (         ,    )
17 static id _instace;
18 //19 //(1)              
20 //(2)       ,           
21 //(3)    init         
22 
23 //    
24 -(id)init
25 {
26 //    __block id obj=nil;
27     static id obj=nil;
28     static dispatch_once_t onceToken;
29     dispatch_once(&onceToken, ^{
30         if ((obj=[super init]) != nil) {
31             //         
32             //....
33             //        self.muscis=[NSMutableDictionary dictionary];
34             //        self.muscis[@"1.mp3"]=1mp3  ;
35             //        self.muscis[@"2.mp3"]=2mp3  ;
36         }
37     });
38     self=obj;
39 
40     return self;
41 }
42 
43 
44 //     ,       ,           
45 +(id)allocWithZone:(struct _NSZone *)zone
46 {
47 
48     //           
49     static dispatch_once_t onceToken;
50     dispatch_once(&onceToken, ^{
51         _instace=[super allocWithZone:zone];
52     });
53     return _instace;
54 }
55 
56 //   
57 +(id)sharedAudioTool
58 {
59   //             
60     static dispatch_once_t onceToken;
61     dispatch_once(&onceToken, ^{
62         _instace=[[self alloc]init];
63     });
64     return _instace;
65 }
66 
67 +(id)copyWithZone:(struct _NSZone *)zone
68 {
69     return _instace;
70 }
71 @end

YYAudioTool.hファイル
1 #import 
2 
3 @interface YYAudioTool : NSObject
4 //
5 +(id)sharedAudioTool;
6 @end

メインコントローラでオブジェクトを作成するには、次の手順に従います.
 1 //
 2 //  YYViewController.m
 3 //  06-    1
 4 //
 5 //  Created by apple on 14-6-25.
 6 //  Copyright (c) 2014  itcase. All rights reserved.
 7 //
 8 
 9 #import "YYViewController.h"
10 #import "YYAudioTool.h"
11 
12 @interface YYViewController ()
13 
14 @end
15 
16 @implementation YYViewController
17 
18 - (void)viewDidLoad
19 {
20     [super viewDidLoad];
21 //    YYAudioTool *tool1=[[YYAudioTool alloc]init];
22 //    YYAudioTool *tool2=[[YYAudioTool alloc]init];
23     YYAudioTool *tool1=[YYAudioTool sharedAudioTool];
24     YYAudioTool *tool2=[YYAudioTool sharedAudioTool];
25     YYAudioTool *tool3=[[YYAudioTool alloc]init];
26     YYAudioTool *tool4=[[YYAudioTool alloc]init];
27     NSLog(@"%p--%p--%p--%p",tool1,tool2,tool3,tool4);
28 }
29 
30 @end

印刷結果を確認します.
 
説明:プログラム全体に1つのオブジェクトインスタンスしか作成されません.
4.static補足:
注意:static id instace=nil;とstatic id instace;instace=nil;の違い