1.KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。KVO其实也是“观察者”设计模式的一种应用。我的看法是,这种模式有利于两个类间的解耦合,尤其是对于业务逻辑与视图控制 这两个功能的解耦合。
观察者模式中的kvo例子:(其中label、button是在xib文件中拖拽的,请大家注意)
Walker.h
#import <Foundation/Foundation.h>
@interface Walker : NSObject
{
NSInteger age;
NSString *name;
}
@property (nonatomic, assign)NSInteger age;
@property (nonatomic, retain) NSString *name;
- (id)initWithName: (NSString*)aName age: (NSInteger)aAge;
@end
Walker.m#import "Walker.h"
@implementation Walker
@synthesize name,age;
- (id)initWithName:(NSString *)aName age:(NSInteger)aAge
{
if (self = [super init]) {
name = aName;
age = aAge;
}
return self;
}
@end
ViewController.h@interface ViewController : UIViewController
{
Walker *walker;
}
@property (nonatomic, retain) Walker *walker;
@end
ViewController.m#import "ViewController.h"
#import "Walker.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *age;
@property (weak, nonatomic) IBOutlet UIButton *plus;
- (IBAction)plusAction:(id)sender;
@end
@implementation ViewController
@synthesize age,plus;
@synthesize walker;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
walker = [[Walker alloc]initWithName:@"李华" age:20];
age.text = [NSString stringWithFormat:@"%ld",(long)walker.age];
[walker addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)plusAction:(id)sender {
walker.age +=2;
NSLog(@"%ld",(long)walker.age);
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"age"] && object == walker)
{
age.text = [NSString stringWithFormat:@"%ld",(long)walker.age];
}
}
@end
2.通知:通知中心实际上是在程序内部提供了消息广播的一种机制。通知中心不能在进程间进行通信。实际上就是一个二传手,把接收到的消息,根据内部的一个消息转发表,来将消息转发给需要的对象。通知中心是基于观察者模式的,它允许注册、删除观察者。
观察者模式中的通知例子:首先我是讲ViewController设为navigationController,然后在上面拖拽了一个button和label。具体代码如下
Viewcontroller.m
#import "ViewController.h"
#import "NewViewController.h"
@interface ViewController ()
- (IBAction)next:(id)sender;
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
@implementation ViewController
@synthesize label;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
//添加监听者
[[ NSNotificationCenter defaultCenter] addObserver: self selector: @selector(update:) name:@"subjectMessage" object: nil ];
}
- (void)update:(NSNotification*)notification{
id text = notification.object;
label.text = text;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)next:(id)sender {
NewViewController *new = [[NewViewController alloc]init];
[self.navigationController pushViewController:new animated:YES];
}
@end
NewViewController.m
#import "NewViewController.h"
@interface NewViewController ()<UITextFieldDelegate>
@property (nonatomic, retain)UITextField *myTextField;
@end
@implementation NewViewController
@synthesize myTextField;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
myTextField = [[UITextField alloc]init];
myTextField.frame = CGRectMake(50, 300, 200, 60);
myTextField.backgroundColor = [UIColor grayColor];
myTextField.delegate = self;
[self.view addSubview:myTextField];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(30, 400, 300, 60);
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:@"输入完成" forState:UIControlStateNormal];
[self.view addSubview:btn];
self.view.backgroundColor = [UIColor whiteColor];
// //点击背景空白处键盘消失3
// self.view.userInteractionEnabled = YES;
// UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(keyboardHide:)];
// [self.view addGestureRecognizer:tapGestureRecognizer];
}
- (void)btnClick:(id)sender
{
[[ NSNotificationCenter defaultCenter] postNotificationName:@"subjectMessage" object:myTextField.text];
[self.navigationController popToRootViewControllerAnimated:YES];
}
//键盘消失方法1
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
//键盘消失方法2
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.myTextField resignFirstResponder];
}
键盘消失方法3*重点背景色射程除了黑色以外别的颜色
//-(void)keyboardHide:(UITapGestureRecognizer*)tap{
// [myTextField resignFirstResponder];
//}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
#import "ViewController.h"
#import "newViewController.h"
@interface ViewController ()<newViewConteollerDelegate>
@property (nonatomic, retain) UILabel *label;
@end
@implementation ViewController
@synthesize label;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
label = [[UILabel alloc]initWithFrame:CGRectMake(40, 100, 300, 50)];\
label.text = @"sad";
label.tintColor = [UIColor redColor];
[self.view addSubview:label];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
[btn setTitle:@"下一页" forState:UIControlStateNormal];
btn.frame = CGRectMake(40, 240, 80, 40);
btn.backgroundColor = [UIColor redColor];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)btnClick:(id)sender
{
newViewController *new = [[newViewController alloc]init];
// new.delegate = self;//代理
//block
new.newViewControllerBlock = ^(NSString *tfText)
{
self.label.text = tfText;
};
[self.navigationController pushViewController:new animated:YES];
}
#pragma -------newViewConteollerDelegate Method-------
-(void)passTextValue : (NSString *) textStr
{
self.label.text = textStr;
}
@end
#import <UIKit/UIKit.h>
@protocol newViewConteollerDelegate <NSObject>
-(void)passTextValue : (NSString *) textStr;
@end
newViewController.h
@interface newViewController : UIViewController
@property (nonatomic, assign) id<newViewConteollerDelegate> delegate;
@property (nonatomic ,copy) void (^newViewControllerBlock) (NSString *tfText);
@end
newViewController.m
#import "newViewController.h"
@interface newViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textField;
- (IBAction)backToViewController:(id)sender;
@end
@implementation newViewController
@synthesize delegate,textField;
@synthesize newViewControllerBlock;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backToViewController:(id)sender {
//代理
// if (delegate && [self.delegate respondsToSelector:@selector(passTextValue:)]) {
// [self.delegate passTextValue:self.textField.text];
// }
//block
if (self.newViewControllerBlock) {
self.newViewControllerBlock(self.textField.text);
}
[self.navigationController popViewControllerAnimated:YES];
}
@end