【一步一步学习iOS开发】【Stanford iOS 公开课】初识iOS,MVC,Objective-C

2 篇文章 0 订阅

1. iOS 系统结构

iOS是基于Unix的系统,整个系统可以粗略的分为四层。分别是Core OS层,Core Services层,Media层以及Cocoa Touch层。

Core OS 层:

Core OS 层主要负责底层相关的功能和服务,例如底层Socket通信,文件系统访问,安全,电源管理等。当然还有Unix Kernel.这层主要是为上层提供服务,所以一般情况下我们不会使用到。相当于Android中的内核和CPP、C层。

Core Services

Core Services层包含手机中的主要服务,如集合(数组,List,Collection),位置服务,网络服务,数据库等。相当于Android中的Framework层,提供各种API供上层使用。

Media

Media层与Core Services层其实差不多,只是iOS中把Media Service单独分层出来提供服务。Media层提供包括Audio,Video,OpenAL,OpenGL,图片,文档等API。

Cocoa Touch

Cocoa Touch 层主要负责用户操作,UI,View等直接与End User打交道的部分。简单的讲就是用户使用手机的时候可以真实感受或者看到的部分.

这一层也是我们编程时会大量使用,甚至主要使用的部分。因此在学习iOS开发的过程中,我们对这一层应该十分注意。

2. MVC 架构

iOS开发中,我们需要使用到的开发模式是MVC模式。MVC即Model,View,Controller。这种开发方式把数据和显示分开,使得同一种数据可以以各种各样的方式展现给用户。而我们需要改动展现方式的时候并不需要改动到Model层的内容。
MVC已经是现在比较流行的设计模式,从大型网站到小型移动APP,都可以看到MVC。实际上,Andoird开发中也是使用的MVC Pattern。

在MVC中各个模块分工明确,合作紧密,保证了我们的代码正确的运行,易于维护和修改。同时具有良好的复用性以及很低的偶合度。

上图中展现了MVC中各个模块之间的通信方式,其中,Controller可以无限制的与Model和View通信——当然了,Controller需要从Model层拿到数据,并告诉View层如何显示这些数据。图中红色的箭头表明,Model与View之间是绝对不能相互通信的,这样做是为了降低模块间的偶合度,方便修改和维护。
另外,图片中的双黄线(道路上的双黄线一样),也表明Model是绝对不能跨过双黄线与View有关系的。其中有点难以理解的是Model与Controller以及View与Controller之间的线是实线和虚线混合。虚线当然表示,Controller可以跨过。实现部分我们下面会讲到。

Model=What?

MVC中的Model,即数据模型,是程序中对现实世界中的问题域的建模,可以表示一辆车,一个人,一本书。但是它只是一个数据结构,只负责保存数据,保证与现实世界中实物的描述。只表示What。
Model并不会直接与Controller或者View通信,你需要不需要它,它都在那里,不增不减不变化。这样就很好的把View和Model分离,使得我们的程序简洁易懂且易维护。

Model与Controller通信

前面有讲到,Model与Controller之间是用实线表示,这表明Model并不能随意的访问Controller。但是有时候我们的Controller是需要接收Model层的消息的,比如我们同时有两个Controller C1和C2,C1正在向用户显示数据库中所有的Model(可以想像成书),C2是图书管理员,正在把书借出支一本。这时候,C2改变了Model中的内容,Model就需要告诉Controller,Oh,我这边的书借出去一本了,你得不显示那本书了。

在MVC模式中,要实现Model层到Controller的通信,我们使用一种类似广播的方式(是不是很熟悉?Android中的Broadcast)。Model中数据变化时,Model会发出一条广播(Hi,to whom may concerned,I’ve changed),然后对这个Model感兴趣的Controller就会收到这个广播并告诉对应的View改变显示方式。

Controller=How the “what” shows on UI.

MVC中的Controller,即控制器,控制着整个程序的逻辑和Model如何显示到View层。Controller把Model和View连接起来,让我们可以在View上看到Controller想要Model层显示的样子。例如,我们在Model存在一个书箱的List,Controller可以控制这个List以书架的形式显示到View层,也可以以Table的形式显示到View层。

View = Your Controller’s minions, Highly re-useable.

MVC中的View层只负责显示以及告诉Controller用户的操作。这一部分是可以高度重用的。例如,同样是一个Button我们可以显示到这个APP里面,也可以在另一个APP里面使用。这一层的大部分UI控件Apple都有提供默认实现。当然我们也可以构造自己的View以用更酷的方式来展现我们的数据。

View与Controller间的通信

Action -> Target方式

在程序运行的过程中,View层其实是需要与Controller通信的,比如用户点击了OK这个Button,View就需要告诉Controller“Hi,用户点击了OK这个Button,我该怎么办?” .当然View层不可能直接调用Controller的某个方法来处理用户点击这个事件,因为View不知道该使用Controller中的哪个方法。
因此我们使用到一种叫做Target的方式来解决这个问题,Controller会事先告诉View,“Hey,如果有人点击了OK,你就叫我运行okButtonClicked()这个方法吧。”。这下问题就解决了,有人点击了OK以后,View就会把这个动作转给Target(即Controller事先告诉View的那个方法)。然后Controller运行完该方法,处理好这个事件以后就会告诉View,好了,我知道了,你该这样,如此,这般的显示就好了。

Delegate方式

View与Controller之间通信还会有另一种情况。假设View是一个ScrollView,当用户在ScrollView上滑动的时候,View会想知道:我应该让用户滑动这个View吗?怎么滑动?这个时候,我们就需要用到代理了。View把类似:Should,Will,did这类问题交给Controller代理,即遇到这样的问题时,View直接交给Controller处理。

3. Objective-C 以及 Model of Card source(a card game)

Objective-C

  • Objective-C是CPP的一个超集,即Objective-C包含了CPP中的所有特性,但又添加了一些CPP中所不具有的特性。
  • Objective-C中只有单继承,不支持多继承。
  • Objective-C中没有GC(垃圾回收机制),所有的对象都存在于堆中(不在栈中),我们需要自己回收不再需要的Objects。
    > all objects lives in heap, not in stack.
    No GC in Objective-C.Reference counting to clear the un-reference Object.
  • Objective-C中的垃圾回收机制是使用的Reference Count机制,当某个对象不再被某个指针引用,就表明这个对象不再被需要,就会被回收。在早期的iOS系统中程序员需要自己维护这个Reference Count,现在这些动作被系统处理了。

在继续讲下去之前,先贴一个Card的代码

在Objective-C中每个对象都会有.h和.m两个部分,.h与CPP中的.h一样,向外部暴露接口。.m中则是实际的私有实现。

以下是对前面代码的一些简单解释(复杂的我也不懂,现学现卖)

  • Card.h

    #import <Foundation/Foundation.h>

 
 

import了基础包,实际上,我们的开发中几乎都要import这个模块,因为这里面包含了所有的基础Objects。


    @interface Card:NSObject

 
 

即声明了一个名为Card的类,Objective-C中声名类的方式与Java中有很大的不同,语法方面的问题大家只能死记硬背了… 其中冒号后面跟了一个NSObject表明Card是继承自NSObject的。NSObject相当于Java中的Object类,基本上是所有Object的基类。


    @property (strong, nonatomic) NSString *contents;

    @property (nonatomic, getter=isFaceUp) BOOL faceUp;
    @property (nonatomic) BOOL unplayable

 
 

这几行代码声明了Card的一系列Property,不像Java中的成员变量这样的东西。Objective-C中使用property来表示。我们需要设置或者取出某个property的值的时候,会用到getter和setter来访问。而真实的数据是存在私有变量中,没有办法直接访问的。

strong/weak pointer

(暂时还没有搞清楚,应该和Java中的强引用和弱引用相关,用于GC的时候~)

nonatomic: no thread safe

nonatomic表示这个property不是线程安全的,所以系统不会对这个property加上一系列的锁,这样会减少运行时的消耗。如果我们的property不需要线程安全,都应该加上这个修饰关键字。

properties (getters & setters)

前面有讲到Objective-C中并没有成员变量这样的说法,一个类中的所有数据都是以property的形式存在的。这样的好处是每个property都有自己的getter和setter,我们可以控制其它类获取这个数据的过程。

右边.m的部分中有这样的代码:


    - (BOOL)isFaceUp
    {
        return _faceUp;
    }

    - (void) setFaceUp:(BOOL)faceUp
    {
        _faceUp=faceUp;
    }

    - (BOOL)unplayable
    {
        return _unplayable;
    }

    - (void)setUnplayable:(BOOL)unplayable
    {
        _unplayable = unplayable;
    }

 
 

这段代码其实是在现实中我们不会看到的,这个会是编译器自动生成的Getter和Setter。
默认情况下,生成的getter的名字就是使用的我们声明的property的名字。setter的名字则相对复杂,默认名字是setProperty,其中Property就是我们声明的property名字首字母大写(所以声明property的时候我们要以小写字母开头~)

另外,我们可以个性getter的名字,如下面这段代码把getter的名字改成了isFaceUp,以更符合英语中的语法习惯。


    @property (nonatomic, getter=isFaceUp) BOOL faceUp;

 
 


第一篇就写到这里了,本人菜鸟,边听着没有字幕的Stanford公开课边写下这些东西。各位看官请轻拍,有任何建议欢迎评论。欢迎访问我的个人页面:http://1.pingoflove.sinaapp.com/?p=44 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值