美文网首页
iOS设计模式

iOS设计模式

作者: RyderZhang | 来源:发表于2016-07-19 14:33 被阅读107次
C51062F062783624454E52CFBAC2AA71.jpg

设计模式:并不是一种新技术,而是一种编码经验。
iPhone本身的设计思想就是遵循MVC设计模式。

MVC模式

(1)MVC是软件设计模式的一种,架构级的设计模式
(2)M(Model) 、V(View)、 C(Controller)
Model 模型:主要负责存储和操作数据。

View 视图:主要负责展⽰数据和⽤用户交互

Controller 控制器: 协调M与V之间的关系。//从网络获取数据->赋值给数据模型->将model的数据传递给view 展示(响应view的delegate和datasource⽅方法)->刷新view

好处: 实现了view和model的低耦合(理论上model和view没有任何联系),进⾏行代码的维护、修改和扩展、复用⾮常⽅便提⾼了软件的开发效率,节约了开发成本。

单例模式

就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象。系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.//类方法就是静态方法,方法返回类型前面是+的方法
比如想获得[UIApplication sharedApplication];任何地方调用都可以得到 UIApplication的对象,这个对象是全局唯一的。

代理模式

代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.比如一个工厂生产了产品,并不想直接卖给用户,而是搞了很多代理商,用户可以直接找代理商买东西,代理商从工厂进货.常见的如QQ的自动回复就属于代理拦截,代理模式在iphone中得到广泛应用.

观察者模式(通知、KVO)

当一个物体发生变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来无非就是把所有观察者的对象给这个物体,当这个物体的发生改变,就会调用遍历所有观察者的对象调用观察者的方法从而达到通知观察者的目的。

工厂模式


在做项目里,我们要写很多工具类。
但因为是协作开发,所以有些人写的时候用的是类方法,而有的人是单例模式的实例方法。

1、类方法和单例模式的实例方法,哪个比较好?
第一、这两个方法创建.h和.m文件的方式也不同,前者是category后者是继承NSObject。
第二、工具类的话一般还是用类方法的比较多(NSString, UIView等做的工具方法,那么做category)
第三、
类方法 :直接为类添加添加方法,直接由类自己调用
单例模式的实例方法:就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象(类方法就是静态方法,方法返回类型前面是+的方法 ),也就是创建了一个单例,这样就可以调用里面的方法了。

2、在OC中,方法分为类方法和实例方法。
1、前置加号(+)的方法为 类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把它称为创建实例的工厂方法。
2、前置减号(-)的方法为 实例方法(对象方法,通过创建一个对象来调用),必须使用类的实例才可以调用的。
备注:要把成员变量声明为静态的,必须使用static关键字

无论是爱还是恨,你都需要单例。实际上每个iOS或macOS应用都至少会有UIApplication或NSApplication.
什么是单例呢?Wikipedia是如此定义的://Wikipedia维基百科
在软件工程中,单例是一种用于实现单例的数学概念,即将类的实例化限制成仅一个对象的设计模式。
或者我的理解是:
单例是一种类,该类只能实例化一个对象。

尽管这是单例的实际定义,但在Foundation框架中不一定是这样。
比如NSFileManger和NSNotificationCenter,分别通过它们的类方法defaultManager和defaultCenter获取。尽管不是严格意义的单例,这些类方法返回一个可以在应用的所有代码中访问到的类的共享实例。在本文中我们也会采用该方法。
使用Objective-C实现单例模式的最佳方式向来有很多争论,开发者(包括Apple在内)似乎每几年就会改变他们的想法。当Apple引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0),他们也引入了一个很适合用于实现单例模式的函数。
该函数就是dispatch_once:
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
该函数接收一个dispatch_once用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块,对于本例就用于shared实例的实例化。
dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
Apple的GCD Documentation证实了这一点:
如果被多个线程调用,该函数会同步等等直至代码块完成。
实际要如何使用这些呢?
假设有一个AccountManager类,你想在整个应用中访问该类的共享实例。你可以按如下代码简单实现一个类方法:

+ (AccountManager *)sharedManager {
 
    static AccountManager *sharedAccountManagerInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedAccountManagerInstance = [[self alloc] init];
    });
    return sharedAccountManagerInstance;
 }

这就意味着你任何时候访问共享实例,需要做的仅是:

AccountManager *accountManager = [AccountManager sharedManager];

就这些,你现在在应用中就有一个共享的实例,该实例只会被创建一次。
该方法有很多优势:
1 线程安全
2 很好满足静态分析器要求
3 和自动引用计数(ARC)兼容
4 仅需要少量代码
该方法的劣势就是它仍然运行创建一个非共享的实例:

AccountManager *accountManager = [[AccountManager alloc] init];

有些时候你希望有这种行为,但如果正在想要的是仅一个实例被实例化就需要注意这点。

HttpManager(单例模式的实例方法)

//
//  HttpManager.h
//  LoveLimit
//
//  Created by test on 16/3/3.
//  Copyright (c) 2016年 test. All rights reserved.
//

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

/*****HttpManager是对AFNetworking这个第三方库的再次封装*****/

//在主动里面定义block的类型
typedef void(^SucBlock)(id responseObject);//成功
typedef void(^FailureBlock)();//失败

@interface HttpManager : NSObject

//一个类方法
+(HttpManager *)shareManager;


//在主动里面定义一个copy修饰,SucBlock和FailureBlock类型的属性(block)
//在这里是将SucBlock类型的sucBlock和FailureBlock类型的failureBlock作为参数加在下面的方法中了
//对象方法
-(void)requestWith:(NSString *)urlString parameters:(NSDictionary *)dic sucBlock:(SucBlock)sucBlock failureBlock:(FailureBlock)failureBlock;

@end

//
//  HttpManager.m
//  LoveLimit
//
//  Created by test on 16/3/3.
//  Copyright (c) 2016年 test. All rights reserved.
//

#import "HttpManager.h"

@implementation HttpManager

+(HttpManager *)shareManager
{
    static HttpManager *manager=nil;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        if (!manager) {
            //manager = [[self alloc] init];
            manager=[[HttpManager alloc]init];
        }
    });
    return manager;
}


-(void)requestWith:(NSString *)urlString parameters:(NSDictionary *)dic sucBlock:(SucBlock)sucBlock failureBlock:(FailureBlock)failureBlock{
    AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];
#warning 这儿没有设置网络请求的类型
    //网络请求的类型可以通过运行时自动打印出来,在这里是@"application/json"
    manager.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json",nil];
    [manager GET:urlString parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (sucBlock) {
            sucBlock(responseObject);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error:%@",error);
        if (failureBlock) {
            failureBlock();
        }
    }];
}

@end

NSString(分类中的类方法)

+ (void)test1;

相关文章

网友评论

      本文标题:iOS设计模式

      本文链接:https://www.haomeiwen.com/subject/fpbmjttx.html