设计模式笔记,cocoa设计模式笔记

枚举器
类似于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 delegate;

待续
Tags:  cocoa笔记 cocoa 设计模式笔记

延伸阅读

最新评论

发表评论