框架学习



1.IOS Cocoa简介

Cocoa是OSX 和IOS操作系统的程序的运行环境(是什么因素使一个程序成为Cocoa程序呢?不是编程语言,因为在Cocoa开发中你可以使用各种语言;也不是开发工具,你可以在命令行上就可以创建Cocoa程序。Cocoa程序可以这么说,它是由一些对象组成,而这些对象的类最后都是继承于它们的根类 :NSObject。而且它们都是基于Objective-C运行环境的)。

2.IOS框架层次:

iOS 框架分为四个层次:核心操作系统(core Os layer),核心服务层(Core Services layer),媒体层(Media layer)可触摸层(Cocoa Touch layer)

核心操作系统:是位于IOS系统架构最下面的一层包括文件管理,内存管理,电源管理,以及其他的操作系统任务,可以直接与硬件设备进行交互,作为app开发者不需要与这一层打交道,

核心服务层:可以访问IOS的一些服务

媒体层:通过它我们可以在应用程序中使用各种媒体文件,进行音频和视频录制,图片绘制,以及基础的动画效果

可触摸层:为我们的应用程序开发提供了各种有用的框架,并且大部分与用户界面有关,本质上来说它负责用户再IOS

设备上的触摸交互。提供了基本的系统行为支持

UIkit框架提供了一些程序运行所必须得关键对象,使得App能捕获用户输入和屏幕上显示的内容

3.Cocoa框架

iOS中,Cocoa众多框架中最重要最基本的两个框架是:Foundation 和 UIKit。

Foundation 和界面无关,也可以说和界面无关的类基本是Foundation框架的,和界面相关的是UIKit框架。

这两个框架在系统中处于的位置如图:


4. Foundation框架

好吧,那我们看看两个框架的类组织架构图,第一个先看Foundation的,三个图,包括了Foundation所以的类,图中灰色的是iOS不支持的,灰色部分是OS X系统的。

  


将上图Foundation框架中的类进行逻辑分类如下:

  1. 值对象
  2. 集合 
  3. 操作系统服务 包括下面三个:文件系统和URL   进程间通讯。 这个范畴中的大部分类代表不同的系统端口、套接字、和名字服务器,对实现底层的IPC很有用。NSPipe代表一个BSD管道,即一种进程间的单向通讯通道。   线程和子任务。 NSThread类使您可以创建多线程的程序,而各种锁(lock)类则为彼此竞争的线程在访问进程资源时提供各种控制机制。通过NSTask,您的程序可以分出      一个子进程来执行其它工作或进行进度监控。
  4. 通知
  5. 归档和序列化
  6. 表达式和条件判断
  7. Objective-C语言服务

5. UIKit框架

应用程序可以通过三种方式使用UIKit创建界面
  1.   在用户界面工具(interface Buidler)从对象库里 拖拽窗口,视图或者其他的对象使用。
  2.   用代码创建
  3.   通过继承UIView类或间接继承UIView类实现自定义用户界面

框架类组织架构图:



在图中可以看出,responder 类是图中最大分支的根类,UIResponder为处理响应事件和响应链 定义了界面和默认行为。当用户用手指滚动列表或者在虚拟键盘上输入时,UIKit就生成时间传送给UIResponder响应链,直到链中有对象处理这个事件。相应的核心对象,比如:UIApplication  ,UIWindow,UIView都直接或间接的从UIResponder继承。

Application Kit的类层次树既宽又浅,类层次中最深的类从根类开始只有五个超类,而大多数类的层次都浅得多。类层次中的一些主要分支特别有意思。

Application Kit中最大分支的根是NSResponder类,它负责定义响应者链,即对用户事件进行响应的有序对象列表。当用户进行按键或鼠标点击时,系统就会产生一个事件,并沿着响应者链向上传递,寻找可以响应该事件的对象。任何处理事件的对象都必须继承自NSResponder类。核心的Application Kit类—NSApplication、NSWindow、和NSView—都继承自NSResponder。阅读"核心应用程序架构"部分可以得到有关响应者类的更多信息。

Application Kit类的第二大分支继承自NSCell类。值得注意的是,这组类和NSControl类(继承自NSView)的派生类有大体上的映像关系。对于负责响应用户动作的用户界面对象,Application Kit采用的架构将它们的工作分为控件(control)对象和单元(cell)对象。NSControl和NSCell类以及它们的子类定义了一组常见的用户界面对象,比如按键(button)、滑块(slider)、和浏览器(browser),用户可以通过图形化的操作控制应用程序的某些方面。大多数的控件对象和一个或多个单元对象相关联,单元对象负责实现描画细节和事件的处理。举例来说,一个按键是由一个NSButton对象和一个NSButtonCell对象构成的,进一步的信息请参见"控件和单元架构"部分。

控件和单元的实现机制基于Application Kit的一个重要设计模式:目标-动作(target-action)机制。单元对象可以保留用户点击(或在单元上进行某种动作)时应该发送给特定对象的消息标识信息。当用户操作一个控件时(比如用鼠标点击控件),控件就从它的单元对象抽出必要的信息,并向目标对象发送动作消息。目标-动作机制使您可以指定目标对象及应该调用的方法,从而赋予用户动作某种意义。您通常可以使用Interface Builder来对目标和动作进行设置,只要按住Control键,同时将鼠标指针从控件对象拖拽到应用程序或其它对象就可以了。您也可以通过编程的方式来设置目标和动作。

Application Kit中另一个基于设计模式的机制是委托(delegation)机制。用户界面上的很多对象,比如文本框和表视图,都定义了委托。委托对象代表被委托对象进行各种动作,或者与之相互协作,因此可以在用户界面操作中实现特定的应用程序逻辑。有关委托、目标-动作、以及Application Kit的其它范式和机制的更多信息,请参见"和对象进行通讯"部分。有关这些范式和机制的基础设计模式的讨论,请参见"Cocoa的设计模式"部分。

下面部分将简要地描述Application Kit的某些能力及其架构的某些方面,还有一些类和协议。在描述时按照图1-9和图1-10所示的类层次图对类进行分组。

通用的用户界面类

在用户界面的总体功能方面,Application Kit提供了如下几个类:

全局应用程序对象。 每个应用程序都使用一个NSApplication类的单件实例来控制主事件循环、跟踪应用程序的窗口和菜单、将事件分发给恰当的对象(即应用程序本身或者它的一个窗口)、建立高级别的自动释放池、以及接收应用程序级别的事件通告。NSApplication对象有一个委托对象(由您来分配),在应用程序启动或终止、被隐藏或被激活、即将打开用户选择的文件等的时候,委托对象会得到通知。通过设置NSApplication对象的委托对象并实现相应的委托方法,您就可以定制应用程序的行为,而不必生成NSApplication的子类。"核心应用程序架构"部分对这个单件应用程序对象进行详细的讨论。

窗口和视图。窗口和视图类,即NSWindow和NSView,继承自NSResponder类,可以对用户动作进行响应。NSApplication对象内维护着一个NSWindow对象的列表—应用程序的每个窗口都有一个对应的对象,而每个NSWindow对象都维护一些具有一定层次结构的NSView对象。视图层次用于窗口内部的描画和事件处理。NSWindow对象负责处理窗口级别的事件,将其它事件分发给窗口中的视图对象,并为视图对象提供一个描画区域。NSWindow对象也有一个委托,用于定制窗口的行为。

NSView是显示在窗口中的所有对象的超类。所有的NSView子类都需要借助图形函数来实现自己的描画方法;drawRect:是一个基本方法,在创建新的NSView时,需要重载这个方法。

"核心应用程序架构"部分也对NSView和NSWindow对象进行描述。

Cocoa绑定的控制器类。NSController是一个抽象类,它的具体子类有NSObjectController、 NSArrayController、和NSTreeController,它们是Cocoa绑定实现的一部分。这个技术可以自动同步存储在对象中的应用程序数据和该数据在用户界面上的表现。有关这些类型的控制器对象的描述请参见"模型-视图-控制器设计模式" 部分。

面板(对话框)。NSPanel是NSWindow的子类,用于显示一些短暂的、全局的、或紧急的信息。举例来说,您可以使用一个NSPanel(而不是NSWindow)的实例来显示错误信息,或请求用户对特殊或不正常的情况进行响应。Application Kit为您实现一些常用的对话框,比如Save、Open、和Print对话框,用于保存、打开、和打印文档。将这些对话框用于各种应用程序的公共操作,可以给用户一个统一的观感。

菜单和光标。NSMenu、NSMenuItem、和NSCursor类负责定义应用程序显示给用户的菜单和光标的行为和外观。

分组和滚动视图。 NSBox、NSScrollView、和NSSplitView类用于为窗口中的视图集合或其它视图对象提供图形“附件”。您可以通过NSBox类将窗口中的元素分组,并为整组元素描画一个边界。NSSplitView类可以在垂直或水平方向附加一些视图,并为每个视图分配一定的公共区域,用户可以通过滑动控制条来重新分配视图的区域。NSScrollView类及其辅助类,NSClipView,为用户提供一个滚动机制,以及让用户初始化和控制滚动的图形对象。NSRulerView类则可以为一个滚动视图添加标尺和标志。

表视图和大纲视图。NSTableView类以行列的方式显示数据。NSTableView可以很好地(但不仅限于)用于显示数据库记录,在这种场合下,一行对应于一条记录,列则包含记录属性。用户可以对单独的单元进行编辑,以及重新排列各个列。您可以通过设置委托和数据源对象来控制NSTableView对象的行为和内容。大纲视图(即NSOutlineView的实例,是NSTableView的子类)提供了另一种显示表格数据的方法。通过NSBrowser类,您可以为用户创建一个显示和漫游层次数据的对象。

文本和字体

NSTextField类实现了一个简单的可编辑文本输入框,NSTextView类则为更大的文本体提供更为广泛的编辑特性。

NSTextView是抽象类NSText的子类,定义了扩展文本系统的接口。NSTextView支持富文本、添附文件(图形文件及其它)、输入管理和按键绑定、以及标识文本属性,可以和Font窗口及Font菜单、标尺及段落风格、Serivces工具、还有剪贴板(Clipboard)等组件互相协作。NSTextView还允许通过委托和通告来进行定制—您很少需要从NSTextView派生出子类,也很少需要以编程的方式创建NSTextView的实例,因为Interface Builder选盘上的一些对象,比如NSTextField、NSForm、和NSScrollView,已经包含了NSTextView对象了。

通过NSTextStorage、NSLayoutManager、NSTextContainer、和其它相关的类,还可能实现更为强大、更具创造力的文本操作(比如在一个圆里进行文本编辑)。Cocoa文本系统还支持列表、表格、和非连续的文本选择。

NSFont和NSFontManager类用于封装和管理字体的家族、尺寸、和变体。对于每种不同的字体,NSFont类定义一个对象与之对应。这些对象都可以表示很多数据,为了提高效率,它们可以在应用程序中的所有对象之间共享。NSFontPanel类定义了在用户界面上显示的Font窗口。

图形和颜色

NSImage和NSImageRep负责封装图形数据,您可以通过这些类轻松而高效地访问存储在磁盘文件或显示在屏幕上的图像。每个NSImageRep的子类都知道如何描画特定类型的源数据代表的图像。NSImage类可以为一个图像提供多种表示,还实现了诸如缓存这样的行为。Cocoa的图像处理和描画的能力都集成在Core Image框架中。

Cocoa的颜色处理由NSColor、NSColorSpace、NSColorPanel、NSColorList、NSColorPicker、和NSColorWell类来支持。NSColor和NSColorSpace类支持一组丰富的颜色格式和表示,包括定制颜色。其它类大多是接口类,负责定义和显示的面板及视图,使用户可以选择和应用颜色。举例来说,用户可以将颜色从Color窗口拖拽到任意的颜色井(color well)。NSColorPicking协议可以用于扩展标准的Color窗口。

NSGraphicsContext、NSBezierPath、和NSAffineTransform类可以实现向量描画,支持图形变换,比如缩放、旋转、和转换等。

打印和传真

NSPrinter、NSPrintPanel、NSPageLayout、和NSPrintInfo类一起,可以将显示在窗口或视图上信息进行打印和传真,还可以创建NSView的PDF表示。

文档和文件系统支持

NSFileWrapper类用于创建与磁盘文件或目录相对对应的对象。NSFileWrapper将文件的内容保留在内存中,以便对其进行显示、修改、以及将它传输给其它应用程序。它还提供一个图标,用于拖拽该文件或将文件表示为附件。您也可以通过Foundation框架中的NSFileManager类来访问或枚举文件和目录内容。NSOpenPanel和NSSavePanel类还提供了便利和熟悉的文件系统界面。

NSDocumentController、NSDocument、和NSWindowController类为创建基于文档的应用程序定义了一个架构(在类的层次框图中,NSWindowController类显示在用户界面组中)。这类程序可以生成包含方式相同、但具有独特排布方式的数据,这些数据可以存储在文件中。在保存、打开、复原、关闭、以及管理这些文档方面,它们具有一些内置或易于得到的能力。

国际化和字符输入支持

如果一个应用程序要在世界其它地方使用,则可能需要根据语言、国家、或文化地域对其资源进行定制或本地化。举例来说,一个应用程序可能需要有独立的日语、英语、法语、和德语版本的字符串、图标、nib文件、或上下文帮助。特定语言的资源文件被存放在程序包目录下的一个子目录下(就是那些带有.lproj扩展名的目录)。您通常可以通过Interface Builder来建立本地化资源文件。有关Cocoa国际化支持的更多信息,请参见"Nib文件和其它应用程序资源"部分。

NSInputServer类、NSInputManager类、和NSTextInput协议一起,为您的应用程序提供访问文本输入管理系统的通道。该系统负责对不同国际化键盘产生的按键进行解释,并将正确的文本字符或Control-key事件递送给文本视图对象(通常由文本类和这些类进行交互,您不必介入)。

操作系统服务

下面这些Application Kit类为您的应用程序提供操作系统支持:

和其它应用程序共享数据。 NSPasteboard类定义了剪贴板,可以存储从应用程序拷贝出来的数据,并使其它希望使用该数据的应用程序可以访问。NSPasteboard实现了大家熟悉的剪切-拷贝-粘贴操作。通过剪贴板,NSServicesRequest协议为应用程序间的数据传递定义一种基于注册服务的通讯机制(剪贴板在用户界面上实现为Clipboard)。

拖拽。只需要少量的编程工作,定制的视图对象就可以被拖拽到任意地方。只要遵循NSDragging...协议,对象就可以变成拖拽机制的一部分;可拖拽的对象遵循NSDraggingSource协议,而目的对象(拖拽对象的接受者)则遵循NSDraggingDestination协议。Application Kit隐藏了所有的光标跟踪和拖拽图像显示的细节。

拼写检查。您可以通过NSSpellServer类来定义一个拼写检查服务,并将它作为服务提供给其它应用程序。通过NSSpellChecker类可以将您的应用程序连接到拼写检查服务上。NSIgnoreMisspelledWords和NSChangeSpelling协议用于支持拼写检查机制。

Interface Builder支持

NSNibConnector类是一个抽象类,它和两个具体子类NSNibControlConnector和NSNibOutletConnector一起,表示Interface Builder上的连接。NSNibControlConnector负责管理Interface Builder中的动作连接,NSNibOutletConnector则管理插座变量连接。

带有Cocoa API的其它框架

作为标准的Mac OS X安装的一部分,苹果系统中还包含(除了Foundation和Application Kit框架外)一些使用Cocoa编程接口的框架(它们也可能使用Carbon或其它类型的编程接口)。您可以通过这些辅助性的框架来为应用程序实现一些期望但不是必须的能力。这些重要的辅助性框架包括:

Core Data—Core Data框架可以帮助应用程序管理模型对象图的整个生命周期,包括关系数据库或平坦文件中数据的持久存储。该框架还包括一些其它特性,比如undo和redo的管理、值的自动正当性检查、将对象的状态改变通知其它对象、以及与Cocoa绑定的集成。

Sync Services—用Sync Services可以将联系人、日历和书签结构、还有您自己的应用程序数据同步起来。您还可以扩展现有的结构。

Address Book—这个框架为联系人和其它个人信息实现了一个中心数据库。使用Address Book框架的应用程序可以和其它应用程序分享这些联系信息,包括苹果的Mail和iChat。

Preference Panes—您可以通过这个框架来创建应用程序动态装载的插件,实现用于录入用户偏好设置的用户界面。这个框架可以应用到您自己或系统级的应用程序。

Screen Saver—Screen Saver框架可以帮助您创建Screen Effects模块,该模块可以通过系统预置(System Preferences)程序来装载和运行。

Web Kit—Web Kit框架中提供一组在窗口中显示万维网内容的核心类。它缺省实现了一些功能,比如显示用户点击的连接。


 2、Cocoa对象

2.1 Objective-C是面向对象的语言

Objective-C和Java C++一样,有封装,继承,多态,重用。但是它不像C++那样有重载操作法、模版和多继承,也没有Java的垃圾回收机制。

2.2 Objective-C的优点

Objective-C语言有C++ Java等面向对象的特点,那是远远不能体现它的优点的。Objective-C的优点是它是动态的。动态能力有三种:

动态类-运行时确定类的对象

动态绑定-运行时确定要调用的方法

动态加载--运行时为程序加载新的模块

2.3 动态能力相关的isa指针

每个Objective-C对象都有一个隐藏的数据结构,这个数据结构是Objective-C对象的第一个成员变量,它就是isa指针。这个指针指向哪呢?它指向一个类对象(class object  记住它是个对象,是占用内存空间的一个变量,这个对象在编译的时候编译器就生成了,专门来描述某个类的定义),这个类对象包含了Objective-C对象的一些信息(为了区分两个对象,我把前面提到的对象叫Objective-C对象),包括Objective-C对象的方法调度表,实现了什么协议等等。这个包含信息就是Objective-C动态能力的根源了。

那我们看看isa指针类型的数据结构是什么样的?如果抛开NSObject对象的其他的成员数据和变量,NSObject可以看成这样:

[cpp]  view plain copy
  1. @interface NSObject <NSObject> {  
  2.      Class    isa;  
  3. }   
不考虑@interface关键字在编译时的作用,可以把NSObject更接近C语言结构表示为:

[cpp]  view plain copy
  1. struct NSObject{  
  2.    Class isa;  
  3.  }  
Class是用typedef 定义的

[cpp]  view plain copy
  1. typedef struct objc_class *Class;  
那NSObject可以这么写了

[cpp]  view plain copy
  1. struct NSObject{  
  2.   objc_class *isa  
  3. }  
那objc_class的结构是什么样的呢?大概是这样的:

[cpp]  view plain copy
  1. struct objc_class {  
  2.      Class isa;  
  3.        
  4.      Class super_class;  
  5.        
  6.      const char *name;  
  7.        
  8.      long version;  
  9.      long info;  
  10.        
  11.      long instance_size;  
  12.      struct objc_ivar_list *ivars;  
  13.      struct objc_method_list **methodLists;   
  14.        
  15.      struct objc_cache *cache;  
  16.      struct objc_protocol_list *protocols;     
  17.  }  
这里会看到,在这个结构体里还有一个isa指针,又是一重指向,是不是有种到了盗梦空间的感觉。不用紧张,take easy,不会有那么多层次的,这里的isa指针指向的是元类对象(metaclass object),带有元字,证明快到头了。那元对象有啥用呢?它用来存储的关于类的版本,名字,类方法等信息。所有的元类对象(metaclass object)都指向 NSObject的元类对象,到头还是NSObject。一共三次:类对象->元类对象->NSObject元类对象。

   为了得到整个类组织架构的信息,objc_class结构里定义了第二个成员变量Class super_class,它指向父类的类对象。说了这么多,可能关系缕不清楚,有道是一张图胜过千言万语


图中可以看出,D3继承D2,D2继承D1,D1最终继承NSObject。下图从D3的一个对象开始,排列出D3 D2 D1 NSObject 类对象,元类对象等关系。


图中的箭头都是指针的指向。

2.4 根类 NSObject

NSObject是大部分Objective-C类的根类,它没有父类。其它类继承NSObject,访问Objective-C运行时系统的基本接口,这样其他类的实例可以获得运行时的能力。


2.4.1 根类和根类协议

NSObject不但是个类名,NSObject也是个协议的名称,参考NSObject协议 , NSObject协议指定了根类必须实现的接口。

2.4.2 根类的主要方法:
  • 分配、初始化、和复制:
alloc和allocWithZone:方法用于从某内存区域中分配一个对象内存,并使对象指向其运行时的类定义。
init方法是对象初始化。
new是一个将简单的内存分配和初始化结合起来的方法。
copy和copyWithZone:

  • 对象的保持和清理:
retain方法增加对象的保持次数。
release方法减少对象的保持次数。
autorelease方法也是减少对象的保持次数,但是以推迟的方式。
retainCount方法返回对当前的保持次数。
dealloc方法由需要释放对象的实例变量以及释放动态分配的内存的类实现。
  • 内省和比较

NSObjec有很多方法可以查询对象的运行时信息。这些内省方法有助于找出对象在类层次中的位置,确定对象是否实现特定的方法,以及测试对象是否遵循某种协议。下面是部分方法 
superclass和class方法(实现为类和实例方法)分别以Class对象的形式返回接收者的父类和类。
您可以通过isKindOfClass:和isMemberOfClass:方法来确定对象属于哪个类。后者用于测试接收者是否为指定类的实例。isSubclassOfClass:类方法则用于测试类的继承性。
respondsToSelector:方法用于测试接收者是否实现由选择器参数标识的方法。instancesRespondToSelector:类方法则用于测试给定类的实例是否实现指定的方法。
conformsToProtocol:方法用于测试接收者(对象或类)是否遵循给定的协议。
isEqual:和hash方法用于对象的比较。
description方法允许对象返回一个内容描述字符串;这个方法的输出经常用于调试(“print object”命令),以及在格式化字符串中和“%@”指示符一起表示对象。

  • 对象的编码和解码

下面的方法和对象的编解码(作为归档过程的一部分)有关:
encodeWithCoder:和initWithCoder:是NSCoding协议仅有的方法。前者使对象可以对其实例变量进行编码,后者则使对象可以根据解码过的实例变量对自身进行初始化。
NSObject类中声明了一些于对象编码有关的方法:classForCoder:、replacementObjectForCoder:、和awakeAfterUsingCoder:。

  • 消息的转发

 forwardInvocation:允许一个对象将消息转发给另一个对象。

  • 消息的派发 

在performSelector开头的一些方法允许你延迟后派发指定消息,而且可以将消息(同步或异步的消息)从辅助线程派发到主线程。

2.5 Cocoa对象生命周期

对象的四种内存管理方式,如下图所示

  •  对象的生命周期—简化视图


  • 保持接收到的对象


  • 拷贝接收到的对象


  • 自动释放池




参考:

1、http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf

2、http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/Introduction.html

3、http://www.cnblogs.com/csutanyu/archive/2011/12/12/Objective-C_memory_layout.html



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值