枚举器

类似于java容器类中的iterator,用以遍历类中的元素
NSDictionary *Mycollection;
NSEnumerator *enumerator=[Mycollection objectEnumerator];
while (instance=[enumerator nextObject]) {
//
}
最新的objective c引入了快速枚举,如下所示:
id instance;
NSDictionary *Mycollection;
NSEnumerator *enumerator=[Mycollection objectEnumerator];
for (instance in Mycollection) {
//
}
NSEnumerator类本身也支持快速枚举,因此可以采用下面的方式反序枚举容器中的数据
id instance;
NSArray *Mycollection;
NSEnumerator *enumerator=[Mycollection objectEnumerator];
for (instance in [Mycollection reverseObjectEnumerator]) {
//
}
要创建自定义的枚举器,那么就要继承NSEnumerator类,重要是override nextObject方法
要实现快速枚举就必须实现NSFastEnumeration协议,主要是实现以下方法
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
执行选择器和延迟执行  
在cocoa中对象的方法调用是采用一种消息的方式来执行的,因此就需要对象能够执行某个操作,发送什么消息才能让对象启动执行某个操作,发送的消息的内容
在cocoa中采用选择器的方式确定发送给对象的消息,并且接收消息的对象使用选择器来选择调用哪个方法
//声明一个selector并初始化
SEL aSelector=@selector(application:didChangeStatusBarFrame:);
//声明一个selector不初始化
SEL bSelector;
//向对象发送selector
id result1=[Mycollection performSelector:aSelector];
id result2=[Mycollection performSelector:@selector(application:didChangeStatusBarFrame:)];
//检测对象是否支持该方法
if ([Mycollection respondsToSelector:aSelector]) {
//OK
}
//动态创建类和selector
id class=[[NSClassFromString(@"TestTableAppDelegate") alloc] init];
[class performSelector:NSSelectorFromString([NSString stringWithFormat:@"setA%i",i])];
selector的基本原理就是apple的运行库通过在类自身内缓冲每个选择器的IMP来快速搜索对应的函数指针,也可以自己找到对应的指针
[Mycollection methodForSelector:aSelector];
[NSDictionary instanceMethodForSelector:aSelector];
归档与解档
说白了就是对象序列化 
NSData *data=[NSKeyedArchiver archivedDataWithRootObject:self.window];
//用户默认数据存取
//存到默认数据中
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"窗口数据"];
通过类似的技术可以把符合协议的任何对象进行归档,下面是协议的定义,第一个用于归档的时候,第二个用于解档的时候
@protocol NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
@end
对象要支持归档与解档就必须实现NSCoding协议
如果对象是继承于父类,那么在实现NSCoding协议的时候还必须调用父类的对应方法,如下所示
@implementation TestClass
@synthesize test1=_test1;
static NSString *CodingKeyTest1=@"Test1";
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.test1 forKey:CodingKeyTest1];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
if (nil!=(self=[super initWithCoder:aDecoder])) {
[self setTest1:[aDecoder decodeObjectForKey:CodingKeyTest1]];
}
return self;
}
@end
cocoa单态模式举例
书上的例子很多是错误的,不知道怎么搞的
static TestClass *_shareInstance=nil;
- (void)encodeWithCoder:(NSCoder *)aCoder{
_test2=@"test";
self->_test2=@"test2";
[aCoder encodeObject:self.test1 forKey:CodingKeyTest1];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
if (nil!=(self=[super initWithCoder:aDecoder])) {
[self setTest1:[aDecoder decodeObjectForKey:CodingKeyTest1]];
}
return self;
}
+ (id)hiddenAlloc{
return [super alloc];
}
//单态模式,不允许创建对象
+ (id)alloc{
return [[self shareInstance] retain];
}
+ (id)new{
return [self alloc];
}
+ (id)allocWithZone:(NSZone *)zone{
return [[self shareInstance] retain];
}
- (id)copyWithZone:(NSZone *)zone{
return [[self shareInstance] retain];
}
- (id)mutableCopyWithZone:(NSZone *)zone{
[self copyWithZone:zone];
return self;
}
+ (TestClass*)shareInstance{
if (_shareInstance==nil) {
_shareInstance=[[super allocWithZone:NULL] init];
}
return _shareInstance;
}
通知
书上的例子很多是错误的,不知道怎么搞的
所谓通知也就是消息监听响应模式,和MFC的实现有些类似,下面给个例子
要想对象能够接收消息,那么就必须先把对象注册到对象通知中心
typedef  struct {
int id;
float  height;
unsigned char  flag;
}MyTestStruct;
//将对象注册到消息接收泵中
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidChangeSelection:) name:@"NSTextViewDidChangeSelection" object:nil];
//对象接收到消息做出对应处理的代码
+ (void)textViewDidChangeSelection:(NSNotification *)aNotification{
NSValue *oldValue=[[aNotification userInfo] objectForKey:@"用键值查找数据"];
MyTestStruct _teststruct;
[oldValue getValue:&_teststruct];
NSLog(@"%f打印结果咯",_teststruct.height);
}
//发送消息给对象
- (void) postMessage{
//发送通知
MyTestStruct _teststruct;
_teststruct.id=0;
_teststruct.height=10.2;
NSValue *_value=[NSValue valueWithBytes:&_teststruct objCType:@encode(MyTestStruct)];
NSDictionary *_dic=[[NSDictionary alloc] initWithObjectsAndKeys:_value, @"用键值查找数据",nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"NSTextViewDidChangeSelection" object:self userInfo:_dic];
}
委托
说白了,就是另外一个对象的引用
比如A要给B发送消息,那么A中就保存一个B的实例引用,所以在cocoa的类中很多内部都有个无类型的实例变量
id delegate;
再比如资源文件创建的窗口也有一个delegate,这个delegate要连接到某个类的delegate,那么这个类的委托就可以这样声明
@property(nonatomic,readwrite,assign) IBOutlet id delegate;
也可以定义成符合某种protocol的委托,如下:
@property(nonatomic,readwrite,assign) IBOutlet id<UITableViewDelegate> delegate;
插座 目标  动作
插座变量主要用于连接Nib文件创建的实例,在从nib文件中加载并初始化了所有对象之后,将给加载的每个对象发送一条如下所示的消息
- (void)awakeFromNib;
对象接收到这个消息后就会把它的所有插座变量都设置为在Interface Builder中给它们提供的值
所谓目标就是target,在cocoa中很多类都提供了一个名为target的插座变量和对应名为action的实例变量
NSControl  NSActionCell  NSMenuItem实现了setTarget方法来设置目标
任何返回void并且接受一个对象参数的方法都可以用作动作
用setAction方法来设置动作
不管发送动作消息是为了干什么,都是使用NSApplication类的-sendAction:to:from:方法来完成发送
NSApplication类是一个单态类,因此发送动作时一般使用如下
[[UIApplication sharedApplication] sendAction: to: from: forEvent:];
响应者链
在cocoa中所有响应用户输入的对象都是抽象类NSResponder的子类
当用户处理应用程序时,cocoa会自动跟踪用户的焦点位于何处,当前正在接收键盘输入的窗口称为"关键"窗口,当前具有焦点的文档称为“主”文档,主文档关联的窗口称为“主”窗口,在cocoa中应用程序会自动追踪关键窗口和主窗口,下面的方法分别获得引用
[[UIApplication sharedApplication] keyWindow];//iphone
[[NSApplication sharedApplication] mainWindow] ;//macos
调用
大部分人都认为selector与消息名称是一回事,实际上不完全是,selector没有提供任何类型信息,当需要构造一个消息的时候就需要知道每个参数的类型和返回值的类型,这种类型信息就称为方法签名(method signature)。
NSMethodSignature类封装了这种信息,使用示例如下
MyDocument *mydoc;
NSMethodSignature *mySig=[mydoc methodSignatureForSelector:@selector(window:shouldDragDocumentWithEvent:from:withPasteboard:)  ];
使用NSInvocation可以发送消息,创建它的实例,配置后可以多次使用,并获得返回值 ,具体的实例就不写了,参考下面的网址吧
http://www.cnblogs.com/chenjunbiao/archive/2011/04/20/2022197.html
享元
享元用来封装非对象数据,使得可以在上下文中使用,并且在需要大量实例时,享元减少了存储需求
如 NSNumber  NSValue 
NSDate;
NSDecimalNumber;
NSDate;
NSCalendarDate;
NSString;
NSURL;
NSFileHandle;
NSPipe;
NSAffineTransform;  都是享元
NSColor ,NSFont;这些享元缓存并重用对象
[NSColor redColor];返回同一个共享实例,下一次请求还是用的同样的一个实例
装饰器 Decorator
就是对象之间的复合,减少类的数量, has-a
用于隐藏复杂性的模式
就是把资源杂七杂八的打包一起
NSString *_p_w_picpathPath=[[NSBundle mainBundle] pathForResource:@"p_w_picpathName" ofType:@"tiff"];
获得可执行程序所在的包
NSBundle *_budle=[NSBundle bundleForClass:[NSString class]];
动态加载可执行代码
NSSearchPathForDirectoriesInDomains  //函数可以获取所有的包路径
_budle=[NSBundle bundleWithPath:@"路径"];//动态加载包
BOOL isLoaded=[_budle load];//强制包的可执行代码链接进应用程序中
id class1=[_budle classNamed:@"类名"];//访问包中的类
类簇
Class Cluster模式给复杂的底层实现提供了一个简单的接口
类簇的主要动机就是为了屏蔽内部实现的复杂性,尽量提供简单的接口
类簇模式利用的技术依赖于cocoa的两阶段创建模式,两阶段即内存分配与初始化
利用两阶段创建,首先从+alloc 返回指向未初始化的新实例的存储空间指针,然后利用-(id)init方法的某个遍体初始化新实例
因此通过init返回的可能就是公共接口的某个子类的实例,在init方法中首先要释放掉已经分配的抽象基础类的实例,然后创建可以返回的想要的具体的子类的实例。
类簇的方式提供了简单的接口,但是复杂化了子类的创建
管理者模式
顾名思义管理者就是管理其他类的实例的类,cocoa中的NSFileManager NSFontManager NSInputManager NSLayoutManager
在应用程序设计中通常具有一个对象的集合,这些对象需要是唯一的,但是他们并不是单例
例如字体,字体可以有多种不同的字体,但是同一个字体在系统中有一个实例就够了
基本完

转载于:https://blog.51cto.com/no001/637790

cocoa设计模式笔记相关推荐

  1. Swift互用性:采用Cocoa设计模式(Swift 2.0版)-b

    本页包含内容: 委托(Delegation) 错误处理(Error Handling) 键值观察(Key-Value Observing) Target-Action模式(Target-Action) ...

  2. 设计模式笔记——代理模式

    设计模式笔记--代理模式 代理模式介绍 代理模式通常是介于请求方和提供方的一个中介系统,请求方是发送请求的一方,提供方是根据请求提供相应资源的一方 Web中的代理服务器就是一个例子,客户端向代理服务器 ...

  3. Java设计模式笔记——七个结构型模式

    系列文章目录 第一章 Java设计模式笔记--七大设计原则 第二章 Java设计模式笔记--六个创建型模式 文章目录 系列文章目录 一.适配器模式 1.概念 2.类适配器 3.对象适配 4.缺省适配器 ...

  4. 软件设计师——设计模式笔记上

    软件设计师--设计模式笔记上(创造型5种) 设计模式的主要目的 设计模式的原则 1.工厂方法模式(类模式) 意图 适用性 代码实现 2.抽象工厂模式(对象模式) 意图 适用性 代码实现 3.生成器模式 ...

  5. 设计模式笔记(1)---开篇(文章索引)

    概念 设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案. 面向对象的设计模式描述了面向对象设计过程中,在特定场景下类与相互通讯的对象之间常见的组织关系. 设计模式与面向对象 面向对象设计模 ...

  6. java观察者模式本质_6.[研磨设计模式笔记]观察者模式

    1.定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新. 2.解决问题 --订阅报纸 看起来订阅者是直接根有据打交道,但实际上,订阅者的订阅数据 ...

  7. grasp设计模式应用场景_grasp设计模式笔记回顾

    根据讲师所讲做了一下笔记以便自己能方便学习: ------------------------------------------grasp设计模式: grasp(general responsibi ...

  8. 设计模式笔记六:适配器模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出(本文基本照搬,因为比较简单) 适配器模式(Adapter Pattern)是作为两个不兼 ...

  9. 3. 狂神的设计模式笔记-代理模式

    文章目录 一.静态代理 1.1 角色分析: 1.2 代码实现 创建客户 1.3 深入理解静态代理 二.动态代理 2.1 代码实现 本文笔记来自于:狂神的设计模式 代理模式的分类: 静态代理 动态代理 ...

  10. 【笔记】设计模式 | 5种设计模式笔记整理

    跟着b站的设计模式教程学的,以下是目前学习了的5种设计模式的笔记整理 设计模式简介 软件设计的现状:由于客户需求等原因需要频繁的变更软件内部的代码.所以能否设计出复用性尽可能高的程序以解决软件设计的复 ...

最新文章

  1. python练习题(python之“求一个数的阶乘并求结果中从后向前数第一个不为0(零)的数” 等)
  2. faster rcnn接口_Faster R-CNN教程
  3. 一文看懂BATH新基建:5G是基础,AI是内核
  4. UA MATH636 信息论8 线性纠错码的解码算法
  5. Weka学习三(ensemble算法)
  6. 具有Aspects的Java中的Mixin –用于Scala特性示例
  7. 使用节点或Express返回JSON的正确方法
  8. UCRT: VC 2015 Universal CRT, by Microsoft
  9. lisp实心圆点怎么画_实心圆点_实心小圆圈符号怎么打出来?
  10. meltdown官方POC原理分析和踩过的坑
  11. 许知远:嗨!Julia
  12. python关闭指定浏览器页面_如何用Python关闭打开的网页
  13. Could not find acceptable representation 原因探究
  14. Unity 按钮反馈 果冻弹跳
  15. C#通过ToLower()方法将字符串转换成小写的代码
  16. android仿钉钉日程日历,Flutter仿钉钉考勤日历的示例代码
  17. Mathmatica简介
  18. 【Wifi模块】使用基于CP2102のWifi模块连接阿里云
  19. SAP VK13 提示 内部错误:T IVAKE F IVAKE_INSERT I MV130F0I
  20. 程序员,这些跨年姿势已就位,请查收~

热门文章

  1. 银联支付接口常见错误总结
  2. 当第一资本、高盛、摩根士丹利等巨头纷纷启用CDO时,您想到了什么?
  3. 安武:被刷屏的德勤财务机器人(RPA)到底是什么?
  4. 《程序员》: Andrew Ng谈Deep Learning
  5. 啥是数据湖?老子(zǐ)告诉你 | 凌云时刻
  6. Gartner 解析容器新发展, 阿里云、AWS布局最完善
  7. 数据库服务器操作系统升级方案,PostgreSQL 数据库跨版本升级常用方案解析
  8. 【基础教程】基于matlab处理音频文件基本用法【含Matlab源码 886期】
  9. 【图像融合】基于matlab GUI拉普拉斯金字塔+小波变换图像融合【含Matlab源码 857期】
  10. 【游戏】基于 matlab GUI lanchester作战模拟设计【含Matlab源码 426期】