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:@"books.@avg.price"]; 求平均值

    NSNumber *sumNumber = [p valueForKeyPath:@"books.@sum.price"];//求和

    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 = @[@"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值