ios项目总结一:开发中常用的设计模式
一、单例设计模式
1、应用场景: 程序运行期间,在内存中只有一个实例存在,主要用于资源共享,对硬件的访问等等
2、优点: 跨模块,解耦合,使用简单
3、敏捷原则: 单一职责原则
4、SDK实例:
- UIApplication类提供了 +sharedAPplication方法创建和获取UIApplication单例
- NSBundle类提供了 +mainBunle方法获取NSBundle单例
- NSFileManager类提供了 +defaultManager方法创建和获得NSFileManager单例。(PS:有些时候我们得放弃使用单例模式,使用-init方法去实现一个新的实例,比如使用委托时)
- NSNotificationCenter提供了 +defaultCenter方法创建和获取NSNotificationCenter单例(PS:该类还遵循了另一个重要的设计模式:观察者模式)
- NSUserDefaults类提供了 +defaultUserDefaults方法去创建和获取NSUserDefaults单例
5、自定义实例:使用宏定义快速实现单例设计模式
1、项目中增加一个Singleton.h文件
2、编辑新增加的Singleton.h文件,添加如下代码
// .h
#define single_interface(class) + (class *)shared##class;
// .m
// \ 代表下一行也属于宏
// ## 是分隔符
#define single_implementation(class) \
static class *_instance; \
\
+ (class *)shared##class \
{ \
if (_instance == nil) { \
_instance = [[self alloc] init]; \
} \
return _instance; \
} \
\
+ (id)allocWithZone:(NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
if (_instance == nil) { \
_instance = [super allocWithZone:zone]; \
} \
return _instance; \
}
3、自己需要实现一个单例的时候,只需要在.h文件中添加声明:single_interface(dataBaseManager);在.m文件中添加实现:single_implementation(dataBaseManager)就可以了。参考下面代码的实现:
单例对象头文件:
// // SingleTest.h // XXX // // Created by wushukai on 15/7/8. // Copyright (c) 2015年 mzk. All rights reserved. // #import <Foundation/Foundation.h> #import "Singleton.h" // 包含单例实现的宏定义的头文件 @interface SingleTest : NSObject single_interface(SingleTest) // 声明该单例 @property (nonatomic, strong) NSString *MyName; @end
单例对象源文件:
//
// SingleTest.m
// XXX
//
// Created by wushukai on 15/7/8.
// Copyright (c) 2015年 mzk. All rights reserved.
//
#import "SingleTest.h"
@implementation SingleTest
single_implementation(SingleTest) // 实现该单例
-(id)init // 在init里面初始化该单例的相关数据
{
self = [super init];
if (self)
{
self.MyName = @"我是一个单例";
}
return self;
}
@end
单例调用者头文件:
// // callSingleTest.h // XXX // // Created by wushukai on 15/7/8. // Copyright (c) 2015年 mzk. All rights reserved. // #import <Foundation/Foundation.h> @interface callSingleTest : NSObject @end
单例调用者源文件:
//
// callSingleTest.m
// XXX
//
// Created by wushukai on 15/7/8.
// Copyright (c) 2015年 mzk. All rights reserved.
//
#import "callSingleTest.h"
#import "SingleTest.h" // 调用的时候,包含单例的头文件
@implementation callSingleTest
-(id)init
{
self = [super init];
if (self)
{
SingleTest *ST = [SingleTest sharedSingleTest]; // 现在就可以使用单例对象了
NSLog(@"ST的名字 = %@", ST.MyName);
}
return self;
}
@end
二、代理设计模式
1、应用场景: 这种模式用于一个对象“代表”另外一个对象和程序中的其他对象进行交互。当一个类的某些功能需要别人来实现的时候,但是既不明确是些什么功能,也不明确到底由谁来实现,委托代理模式就派上用场了。
2、优点: 使类之间的耦合性更松散。好的代码应该开放扩展,关闭修改。
3、敏捷原则: 开放-封闭原则
4、cocoa框架中的delegate设计模式:
UITableView常用代理方法:前三个为UITableViewDataSource协议代理方法,剩下的为UITableViewDelegate协议代理方法
#pragma mark - 1、设置分组 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView #pragma mark - 2、设置每个组有多少行共有多少行 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section #pragma mark - 3、设置UITableViewCell的内容 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath #pragma mark - 4、设置每个UITableViewCell的行高 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath #pragma mark - 5、设置accessory的点击响应事件 - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath #pragma mark - 6、返回每组头标题名称 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; #pragma mark - 7、返回每组尾部说明 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section; #pragma mark - 8、设置分组页头的高度 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; #pragma mark - 9、设置分组页脚的高度 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section; #pragma mark - 10、将要选中了某一行 -(NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath; #pragma mark - 11、确实选中了某一行 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; #pragma mark - 12、设置划动cell是否出现del按钮,可供删除数据里进行处理 -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath; #pragma mark - 13、设置cell是否可以上下移动 -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
UIScrollView常用的代理方法:
// 1、返回一个放大或者缩小的视图 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; // 2、开始放大或者缩小 - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view; // 3、缩放结束时 - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale; // 4、视图已经放大或缩小 - (void)scrollViewDidZoom:(UIScrollView *)scrollView; // 5、是否支持滑动至顶部 - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView; // 6、滑动到顶部时调用该方法 - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView; // 7、scrollView 已经滑动 - (void)scrollViewDidScroll:(UIScrollView *)scrollView; // 8、scrollView 开始拖动 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView; // 9、scrollView 结束拖动 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate; // 10、scrollView 开始减速(以下两个方法注意与以上两个方法加以区别) - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView; // 11、scrollview 减速停止 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
UITextField常用代理方法:
#pragma mark - 在用户每次输入的时候都会调用,返回YES代表允许输入 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; #pragma mark - 在文本框准备聚焦的时候调用,返回NO代表不允许聚焦(编辑) - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; #pragma mark - 当文本框开始获得焦点的时候调用 - (void)textFieldDidBeginEditing:(UITextField *)textField; #pragma mark - 在文本框准备失去焦点(退出键盘)的时候调用,返回YES代表允许退出键盘 - (BOOL)textFieldShouldEndEditing:(UITextField *)textField; #pragma mark - 当用户失去焦点的时候调用 - (void)textFieldDidEndEditing:(UITextField *)textField;
UIPickerView常用代理方法:
#pragma mark - 数据源方法 #pragma mark - 有多少列 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView; #pragma mark - 第component列有多少行 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component; #pragma mark - 每行显示什么内容、第component列第row行显示什么文字 - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component; #pragma mark - 代理方法 #pragma mark - 手动选中了某一行 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
UIImagePickerController常用代理方法:
#pragma mark - 选中了图片或者视频之后调用 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
代理定义方:顾客
// // Client.h // basefoundationTest // // Created by wushukai on 15/7/9. // Copyright (c) 2015年 mzk. All rights reserved. // #import <Foundation/Foundation.h> @protocol ClientDelegate <NSObject> -(void)hungry; @end @interface Client : NSObject @property(assign, nonatomic) id clientDelegate; // 代理对象 @end
源文件:
// // Client.m // basefoundationTest // // Created by wushukai on 15/7/9. // Copyright (c) 2015年 mzk. All rights reserved. // #import "Client.h" @implementation Client @end
代理实现方:餐馆
头文件:
// // Server.h // basefoundationTest // // Created by wushukai on 15/7/9. // Copyright (c) 2015年 mzk. All rights reserved. // #import <Foundation/Foundation.h> @interface Server : NSObject @end
源文件:
//
// Server.m
// basefoundationTest
//
// Created by wushukai on 15/7/9.
// Copyright (c) 2015年 mzk. All rights reserved.
//
#import "Server.h"
#import "Client.h"
#pragma mark - 遵守代理协议
@interface Server()<ClientDelegate>
@end
@implementation Server
-(id)init
{
self = [super init];
if (self)
{
Client *client = [[Client alloc] init];
client.clientDelegate = self; // 1、设置当前顾客的代理目的地
[client.clientDelegate hungry]; // 2、顾客饿了,通知服务员点餐
}
return self;
}
#pragma mark - 实现顾客的代理方法
-(void)hungry
{
NSLog(@"你饿了,要吃饭,我帮你做");
}
@end
三:MVC设计模式
如下图所示:

1、简介:是一中非常古老的设计模式,通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑划分。
2、组成:MVC是Model(模型)-- View(视图)-- Controller(控制器)。 下面通过使用UITableView显示城市列表来解释。
1、V通常通过两种方式与C交互:
1、Delegate,比如UITableViewDataSource和UITableViewDelegate;
2、Target-action,比如用户在视图上点击了某一个按钮
2、M一般通过两种方式与C交互:
1、Notification;在控制器中注册通知,需要触发的时候,在模型中发送通知
2、KVO;键值对改变通知观察者,在控制器中观察模型数据的变化
3、C一般通过M暴露出来的API对M进行读写操作,比如用户在视图中修改了某个城市的名字,则通过控制器间接修改模型数据
4、C一般通过Outlet与V进行交互
5、V与M之间不进行直接交互,使用C作为中介进行交互
3、优势:使系统层次分明,职责独立,易于维护
4、敏捷原则:对扩展开放,对修改封闭
四:观察者模式
1、简介:被观察者对象状态改变,通知正在对他进行观察的观察者对象,观察者对象根据各自要求做出相应的改变
2、优势:解耦合
3、敏捷原则: 接口隔离原则,开放扩展,封闭修改
4、实例:cocoa框架中的观察者设计模式实例
1、Notification(通知中心)。任何地方可以发送消息,注册观察者的地方可以接收。
2、KVO(key-value-observer)。键值对改变通知观察者。
ios项目总结一:开发中常用的设计模式的更多相关文章
- iOS开发中常用的设计模式
常用的设计模式(一)代理模式应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现.优势:解耦合敏捷原则:开放-封闭原则实例:tableview的 数据源delegate,通过 ...
- Android开发中常用的设计模式
首先需要说明的是,这篇博文灵感来自于 http://www.cnblogs.com/qianxudetianxia/archive/2011/07/29/2121547.html ,在这里,博主已经很 ...
- 根据数据库的表生成项目,项目变为hibernate项目(实际开发中常用)
1. 选择模式为Myeclipse Database Explorer perpective 2. (1)右键建立mysql模板,选择默认的mysql模板 (2)drive name (任意这里取m ...
- Java开发中常用的设计模式(二)---单例模式
一. 懒汉式单例 //懒汉式单例类.在第一次调用的时候实例化自己 public class Singleton { private Singleton() {} private static Sing ...
- Java开发中常用的设计模式(一)---工厂模式
一. 准备工作 1. 本文参考自 自己理解的工厂模式,希望对大家有所帮助 二. 开始 以汽车工厂为例,首先有个汽车类的接口 Car,里面有个开车的方法 drive(),然后有个宝马车的类 BMW 和 ...
- Java开发中常用的设计模式(三)---建造者模式
一. 模式结构 建造者模式主要包含四个角色: Product:产品角色. Builder:抽象建造者.它声明为创建一个Product对象的各个部件指定的抽象接口. ConcreteBuilder:具体 ...
- iOS开发中常用的数学函数
iOS开发中常用的数学函数 /*---- 常用数学公式 ----*/ //指数运算 3^2 3^3 NSLog(,)); //result 9 NSLog(,)); //result 27 //开平方 ...
- .net开发中常用的第三方组件
.net开发中常用的第三方组件 2013-05-09 09:33:32| 分类: dotnet |举报 |字号 订阅 下载LOFTER 我的照片书 | RSS.NET.dll RSS. ...
- Java开发中常用jar包整理及使用
本文整理了我自己在Java开发中常用的jar包以及常用的API记录. <!-- https://mvnrepository.com/artifact/org.apache.commons/com ...
随机推荐
- JS分页方法
/** maxpage 最大页数 */function gotoPage(maxpage){ var gotoPage = document.getElementById(" ...
- vim 基础命令
第一部份:一般指令模式可用的按鈕說明,游標移動.複製貼上.搜尋取代等 移動游標的方法 h 或 向左方向鍵(←) 游標向左移動一個字元 j 或 向下方 ...
- mysql修改数据表名
在使用mysql时,经常遇到表名不符合规范或标准,但是表里已经有大量的数据了,如何保留数据,只更改表名呢? 可以通过建一个相同的表结构的表,把原来的数据导入到新表中,但是这样视乎很麻烦. 能否简单使用 ...
- 第1章 Bootstrap介绍
学习网址:http://www.bootcss.com/ 下载网址:http://v3.bootcss.com/ 下载后一共三个文件夹 css js fonts 引入的文件 <link rel= ...
- Daily Scrum 10.31
今天是万圣节,也是编译课程设计第一次作业截至的日子,但由于大家对时间的合理安排,我们还是完成了一定的任务量. 下面是今天的Task统计: 不仅燃尽图和燃速图出不来,连那个所有迭代状态的图也出不来了.. ...
- Mysql的一些常用命令
Mysql基本操作 创建表: create table test01_02(id varchar(50) not null auto_increment primary key, name nvarc ...
- Unity3d优化
检测方式: 一,Unity3D 渲染统计窗口 Game视窗的Stats去查看渲染统计的信息: 1.FPS fps其实就是 frames per second,也就是每一秒游戏执行的帧数,这个数值越小, ...
- 大数相乘nyoj28
描述我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,我们该如何去计算它并输出它? 输入 输入一个整数m(0<m<=5000) 输出 输出m的阶乘,并在输出结束之后输入一个换行符 ...
- LDA 初见(JGibbLDA-v.1.0 eclipse使用)
参考:Eclipse下使用JGibbLDA使用总结 一.下载和初次使用JGibbLDA 1.导入JGibbLDA-v.1.0项目(参考上面链接) 2.在LDA.java右键“run”--->“r ...
- ThinkPHP 3.2.3 数据缓存与静态缓存
ThinkPHP 3.2.3 中手册中数据缓存的地址是:http://www.kancloud.cn/manual/thinkphp/1835 静态缓存的地址是:http://www.kancloud ...