MVC
MVC, Model, View, Controller
是一种将应用中所有类组织起来的策略
将所有的类分为三块,分别是模型、视图和控制器
Model, View, Controller
-
Model
What your app is(but not how it is displayed)
完全独立于 UI
-
View
controller's minions
控制器要使用的类,视图中的元素是通用的
视图不允许拥有数据,模型拥有数据
-
Controller
How your Model presented to the user(UI logic)
控制 UI 如何工作,非常特定地作用于 UI 工作
通信
-
控制器 -> 模型
控制器需要知道模型的一切,需要有同模型完全通信的能力,按照任何方式使用 API
控制器的作用是将模型呈现给用户,使用视图作为其仆从
控制器需要能够完全,不受限地访问模型
-
控制器 -> 视图
通信同样是不受限的
当有一个属性从控制器指向视图,就称它是一个 outlet,作用是让视图和控制器通信
-
模型 <-> 视图
无法通信,模型完全独立于 UI
视图是通用的 UI 对象,不能与任何特定模型通信
视图需要控制器来为它解释模型
-
视图 -> 控制器
- 通过盲通信(target action 等)
- 通过代理
- 通过数据源
-
模型 -> 控制器
不允许,模型对 UI 一无所知
模型中的事物变化时,控制器需要知道这样的变化——通过 Notification 机制和键值观察
属性
属性是 OBJC 中用来访问实例变量的方式
属性实际上就是一个 getter 方法和一个 setter 方法(并不会对性能有太大影响)
类
每个类有一个头文件.h 和一个实现文件.m
.h 里的是公共 API
.m 里的是私有 API
-
.h
@import Foundation @interface Card: NSObject //@interface <类名(同文件名)> : <父类> //.h 必须指名父类,且只指名一次 @property (strong, nonatomic) NSString *contents; //@property 会声明每一个纸牌实例都需要空间,且在 .h 中自动创建 setter 和 getter 的声明 //对象声明必须使用指针。所有的对象在堆中而不是栈中 //strong 表示在堆中保持这个这个所指的东西,除非没有任何一个强指针指向它则释放(这称为 ARC),是缺省值 //weak 表示除了有 strong 的特性以外,当它被释放时这个指针会指向 nil(对 nil 指针发送消息不会有问题) //nonatomic 非原子性,即禁止多线程 @property (nonatomic, getter=isChosen) BOOL chosen; @property (nonatomic, getter=isMathced) BOOL matched; //原始属性不再堆中,不需要指针,所以不用指定 strong 或 weak //可以在声明时修改 Getter 的名字 - (int)match:(Card *)card; //- 表示实例方法,+ 表示类方法 @end //表示接口的结束,所有的共有 API 都在 @interface 和 @end 之间
-
.m
#import "Card.h" @interface Card() @end //私有声明部分 以 @interface <类名>() 开始,@end 结束 //主要用于属性 @implementation Card @synthesize contents = _contents //@synthesize 与 @property 成对使用,表示使用名为_contents 的实例变量 //iOS7以后可以不用写,默认生成前缀是下划线的实例变量和对应 setter 和 getter //@synthesize 会在 .m 中自动生成 setter 和 getter 的实现 //如果有自己实现的 setter 和 getter ,上面的自动实现会被屏蔽 - (int)match:(NSArray *)otherCards { int score = 0; for (Card *card in otherCards) { if ([!card.contents isEqualToString:self.contents]) { score = 1; //==比较的是指针而不是值,要用 isEqualToString } } } @end //表示私有实现的结束,所有私有实现都在 @implementation 和 @end 之间
网友评论