ios開發中的幾種設計模式

一,單例模式:通過static關鍵詞,聲明全局變量。在整個進程運行期間只會被賦值一次。

/**

 static : 修飾變量

 1> 修飾全局變量

 * 全局變量的作用域僅限於當前文件內部(不加的話別人使用extern關鍵字就能從其他文件訪問這個文件的全局變量了)

 2> 修飾局部變量 :

  * 能保證局部變量永遠只初始化1次,在程序運行過程中,永遠只有1分內存

 * 局部變量的生命週期全局變量類似

 * 但是不能改變作用域

 */


#pragma mark 懶漢式單例 arc

#import "HMMusicTool.h"

@implementation HMMusicTool


static id _instance; //保證這個全局變量只能當前文件可以訪問


/**

 *  alloc方法內部會調用這個方法

 */

+ (id)allocWithZone:(struct _NSZone *)zone

{

    if (_instance ==nil) { //防止頻繁加鎖

        @synchronized(self) {

            if (_instance ==nil) { //防止創建多次

                _instance = [super allocWithZone:zone];

            }

        }

    }

    return _instance;

}


+ (instancetype)sharedMusicTool

{

    if (_instance ==nil) { //防止頻繁加鎖

        @synchronized(self) {

            if (_instance ==nil) { //防止多次init

                _instance = [[self alloc] init];

            }

        }

    }

    return _instance;

}


//copy方法內部會調用這個方法

- (id)copyWithZone:(NSZone *)zone

{

    return _instance;//保證copy方法調用之後也是這一個對象不會產生新的對象,因爲copy可能拷貝產生新的對象

}

@end


////  餓漢式 (不需要掌握)

//#import "HMSoundTool.h"

//@implementation HMSoundTool

//

//static id _instance;

//

///**

// *  當類加載到OC運行時環境中(內存),就會調用一次(一個類只會加載1次)

// */

//+ (void)load

//{

//    _instance = [[self alloc] init];

//}

//

//+ (id)allocWithZone:(struct _NSZone *)zone

//{

//    if (_instance == nil) { // 防止其他創建多次

//        _instance = [super allocWithZone:zone];

//    }

//    return _instance;

//}

//

//+ (instancetype)sharedSoundTool

//{

//    return _instance;

//}

//

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

//{

//    return _instance;

//}

//

/////**

//// *  當第一次使用這個類的時候纔會調用 (如果使用這個類的方法還需要調用父類的這個方法,比如繼承,那麼弗雷德initialize方法也會調用)load的區別就在這

//// */

////+ (void)initialize

////{

////    NSLog(@"HMSoundTool---initialize");

////}

//@end


#pragma mark GCD模式單例  arc


#import <Foundation/Foundation.h>


@interface HMDataTool : NSObject

+ (instancetype)sharedDataTool;

@end


#import "HMDataTool.h"


@implementation HMDataTool

// 用來保存唯一的單例對象

static id _instace;


+ (id)allocWithZone:(struct _NSZone *)zone

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instace = [super allocWithZone:zone];

    });

    return _instace;

}


+ (instancetype)sharedDataTool

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instace = [[self alloc] init];

    });

    return _instace;

}


- (id)copyWithZone:(NSZone *)zone

{

    return _instace;

}

@end


#pragma mark GCD單例模式arc


#import "HMDataTool.h"


@implementation HMDataTool

// 用來保存唯一的單例對象

static id _instace;


+ (id)allocWithZone:(struct _NSZone *)zone

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instace = [super allocWithZone:zone];

    });

    return _instace;

}


+ (instancetype)sharedDataTool

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instace = [[self alloc] init];

    });

    return _instace;

}


- (id)copyWithZone:(NSZone *)zone

{

    return _instace;

}


//arc多了這幾個方法

- (onewayvoid)release{

}

- (id)retain {

    returnself;

}

- (NSUInteger)retainCount {

    return1;

}

- (id)autorelease {

    returnself;

}


@end


#pragma mark 宏實現單例,自定義名稱,適配arc和非arc

創建一個HMSingleton.h文件,.h文件中寫以下宏

// .h文件

#define HMSingletonH(name) + (instancetype)shared##name;


// .m文件

#if __has_feature(objc_arc)


#define HMSingletonM(name) \

static id _instace; \

\

+ (id)allocWithZone:(struct _NSZone *)zone \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [super allocWithZone:zone]; \

}); \

return _instace; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [[self alloc] init]; \

}); \

return _instace; \

} \

\

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

{ \

return _instace; \

}


#else


#define HMSingletonM(name) \

static id _instace; \

\

+ (id)allocWithZone:(struct _NSZone *)zone \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [super allocWithZone:zone]; \

}); \

return _instace; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [[self alloc] init]; \

}); \

return _instace; \

} \

\

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

{ \

return _instace; \

} \

\

- (oneway void)release { } \

- (id)retain { return self; } \

- (NSUInteger)retainCount { return 1;} \

- (id)autorelease { return self;}


#endif


再把HMSingleton.h文件導入pch文件即可

使用的時候就在需要使用的類的.h文件中加一句HMSingletonH .m文件加一句HMSingleton.m即可


二,觀察者模式:KVO是典型的通知模式,觀察某個屬性的狀態,狀態發生變化時通知觀察者。

//1.KVC

#pragma mark -KVC

- (void)viewDidLoad

{

    [super viewDidLoad];

    XLCustom * custom = [[XLCustom alloc]init];

    //<1>

    //原始方法對成員變量進行賦值使用的是setter方法或者點語法

    //原始方法對成員變量進行獲取使用的是getter方法或者點語法

    //    custom.name = @"xuli";

    //    [custom setAge:19];

    //    NSLog(@"%@,%d",[custom name],custom.age);

    //[結論]原始方法對成員變量進行賦值和獲取前提是該成員變量必須具有settergetter方法的聲明和實現部分

    //<2>KVC

    //KVC key-value-coder的縮寫 鍵值編碼的簡稱

    //KVC -------- 對象的屬性或者成員變量進行賦值進行賦值(私有的也可以修改),一般用來替換系統的私有的東西

    /*

     1、先去類中查找是否具有該變量的setter方法的聲明和實現部分 如果具有直接調用setter方法對成員變量進行賦值

     2、如果不具有 繼續查找是否具有以該變量命名的成員變量 如果具有直接賦值

     3、如果不具有 繼續查找是否具有以下劃線開頭以變量命名的成員變量 如果具有直接賦值 如果不具有崩潰

     */

    //KVC 對成員變量進行賦值使用的方法是setValue:forkey(path): 前提是找到賦值的類的對象的指針

    [custom setValue:@"xuli" forKey:@"name"];

    [custom setValue:@(19) forKey:@"age"];

    //KVC 對成員變量進行獲取使用的方法的是valueForkey(path):

    NSLog(@"%@,%d",[custom valueForKey:@"name"],[[custom valueForKey:@"age"] intValue]);

    //1.KeyPathKey的區別

    Person *p = [[Person alloc] init];

    p.dog = [[Dog alloc] init];

    p.dog.bone = [[Bone alloc] init];

    //        p.dog.bone.type = @"狗骨";

    

    //        [p setValue:@"豬骨" forKeyPath:@"dog.bone.type"];

    //        [p.dog setValue:@"豬骨" forKeyPath:@"bone.type"];

    [p.dog.bone setValue:@"豬骨" forKeyPath:@"type"];

    

    NSLog(@"%@", p.dog.bone.type);

    

    //        p.dog.name = @"wangwang";

    //        [p.dog setValue:@"wangcai" forKey:@"name"];

    //        [p.dog setValue:@"larry" forKeyPath:@"name"];

    

    //        [p setValue:@"hashiqi" forKeyPath:@"dog.name"];

    

    //forKeyPath包含了forKey的功能,以後使用forKeyPath就可以了

    //forKeyPath中可以利用.運算符, 就可以一層一層往下查找對象的屬性

    //        [p setValue:@"hashiqi" forKey:@"dog.name"]; // 寫法錯誤

    

    //        NSLog(@"%@", p.dog.name)

    //2.關於KVC中的數據數組 (不常用,知道就好)

    Person *p = [[Person alloc] init];

    Book *book1 = [[Book alloc] init];

    book1.name = @"5分鐘突破iOS開發";

    book1.price = 10.5;

    Book *book2 = [[Book alloc] init];

    book2.name = @"5分鐘突破android開發";

    book2.price = 18.5;

    Book *book3 = [[Book alloc] init];

    book3.name = @"5分鐘突破前端開發";

    book3.price = 20.5;

    Book *book4 = [[Book alloc] init];

    book4.name = @"5分鐘突破PHP開發";

    book4.price = 10.5;

    p.books = @[book1, book2, book3, book4];

    

    // 獲得所有的書名(將所有的書名放到一個數組中)

    //        NSMutableArray *names = [NSMutableArray array];

    //        for (Book *book in p.books) {

    //            [names addObject:book.name];

    //        }

    

    // 取出books數組中每一個元素的name屬性值,放到一個新的數組中返回

    NSArray *names = [p valueForKeyPath:@"books.name"];

    [p valueForKeyPath:@"dog.name"];

    NSLog(@"%@", names);

    //取出數組中的books的價格,再把每一個價格加起來 返回值是NSNumber類型的數據

    //NSNumber *avgNumber = [p valueForKeyPath:@"[email protected]"]; 求平均值

    NSNumber *sumNumber = [p valueForKeyPath:@"[email protected]"];//求和

    NSLog(@"%@", sumNumber);

    //        NSLog(@"%f", [sumNumber doubleValue]);


}


// 2. 使用KVC進行正向和反向傳值

//正向傳值:給下一個界面設一個屬性來接受傳過去的值,在這個界面獲取下一個界面的指針,用指針[next setValue:[UIColor magentaColor] forKey:@"nextColor"];

//反向傳值:在上一個界面設置一個屬性接受傳過來得值,在下一個界面設一個屬性id delegate; 設置下一個界面的屬性是上一個界面的指針.然後用代理(即上一個界面的指針)設置上一個界面的屬性值,這樣就反向傳過去了

// 3. KVO 的使用

#pragma mark - KVO

#import "XLViewController.h"

#import "XLBoy.h"

#import "XLGirl.h"

@interface XLViewController ()

{

    XLBoy * boy;

    XLGirl * girl;

}

@end


@implementation XLViewController


-(void)createUI

{

    NSArray * array = @[@"

發佈了40 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章