05ios开发指南基础基本任务Word格式文档下载.docx
- 文档编号:18644124
- 上传时间:2022-12-30
- 格式:DOCX
- 页数:18
- 大小:415.62KB
05ios开发指南基础基本任务Word格式文档下载.docx
《05ios开发指南基础基本任务Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《05ios开发指南基础基本任务Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
协议,该协议声明的一些附加方法是所有对象的接口所共用的。
此外,NSObject.h(该头文件包含NSObject
的类定义)包含对
NSCopying、NSMutableCopying
和
NSCoding
协议的声明。
当一个类采用这些协议时,它使用对象拷贝和对象编码功能来增加基本对象的行为。
模型类(这些类的实例封装和管理应用程序的数据)经常采用对象拷贝和对象编码协议。
类及相关协议定义的方法,用于创建对象、导航继承链、询问对象的特征和功能、比较对象、拷贝对象和对对象进行编码。
本文章后面的章节描述了绝大多数这些任务的基本要求。
按照对象进行思考
在运行时,每个应用程序都是一个由互相合作的对象组成的网络;
这些对象相互通信以完成应用程序的工作。
每个对象扮演一个角色,负责至少一项任务,并连接到起码一个另外的对象。
(孤立的对象没有多少价值。
)如下图所示,对象网络中的对象同时包含框架对象和应用程序对象。
应用程序对象是自定子类的实例,通常属于框架超类。
一个对象网络的通称为对象图。
您通过引用在对象之间建立这些连接或关系。
引用有多种语言形式,其中包括实例变量、全局变量,甚至局部变量(在有限的范围内)。
关系可以是一对一或一对多,可以表达主从关系或父子关系的概念。
这些关系是一个对象访问其他对象、与其他对象通信或控制其他对象的一种手段。
被引用的对象成为消息的自然接收者。
应用程序中对象之间的消息传递,对于应用程序的功能连贯性至关重要。
就像管弦乐队中的音乐家,应用程序中的每个对象都各自有其角色和特定的行为表现,共同组成了一个应用程序。
一个对象可能会显示椭圆表面对轻按操作作出响应,或者管理一组包含数据的对象,或者协调应用程序生命周期中的主要事件。
但是为了实现它的作用,它必须能够与其他对象通信。
它必须能够发送消息给应用程序中的其他对象,或者能够接收来自其他对象的消息。
对于强耦合对象(即通过直接引用建立相互连接的对象),发送消息轻而易举。
但是对于松耦合对象(也就是说,在对象图中相隔很远),应用程序不得不寻找其他的通信方式。
CocoaTouch和Cocoa框架具有许多机制和技巧,使得松耦合对象之间能够通信(正如下图所示)。
这些机制和技巧,全部基于设计模式(您稍后将会学到更多内容),使得有效地构建稳固的和可扩展的应用程序成为可能。
创建对象
创建对象时,您通常会先分配再初始化。
尽管这是两个分离的步骤,但它们却是紧密相连的。
很多类还可以让您通过调用一个类工厂方法来创建对象。
通过分配并初始化对象来创建对象
为了分配对象,您发送
alloc
消息给该对象的类,来获得该类的一个“原始”(未初始化)的实例。
分配对象时,Objective-C运行时会从应用程序的虚拟内存,为对象分配足够的内存。
除分配内存以外,运行时在分配期间还做了一点别的事,例如将所有实例变量设定为零。
分配原始实例后,您必须立即对它初始化。
初始化将一个对象的初始状态(即它的实例变量和属性)设定为合理的值,然后返回对象。
初始化的目的在于返回有用的对象。
在框架中,您会发现很多称为初始化程序的方法,它们将对象初始化并且具有相似的格式。
初始化程序为实例方法,它们以
init
开始,并返回一个类型为
id
的对象。
声明
方法供其他所有类继承。
其他类可以声明各自的初始化程序,各有专属的关键词和参数类型。
例如,NSURL类声明以下初始化程序:
-(id)initFileURLWithPath:
(NSString*)pathisDirectory:
(BOOL)isDir
分配对象和将对象初始化时,您将分配调用嵌套在初始化调用内。
以上面的初始化程序为例:
NSURL*aURL=[[NSURLalloc]initFileURLWithPath:
NSTemporaryDirectory()isDirectory:
YES];
作为一种安全的编程实践,您可以测试返回的对象以验证该对象已经创建。
无论在哪个阶段发生对象不可创建的事情,初始化程序都会返回
nil。
尽管Objective-C可让您发送消息到
nil
而不会有负面后果(例如,不会抛出异常),您的代码可能没有预期结果,因为它没有调用任何方法。
您应该使用初始化程序返回的实例,而不是由
方法返回的实例。
通过调用类工厂方法创建对象
您还可以通过调用类工厂方法来创建对象——类工厂方法是一种用于分配、初始化实例并返回一个它自己的实例的类方法。
类工厂方法很方便,因为它们允许您只使用一个步骤(而不是两个步骤)就能创建对象。
它们采用以下形式:
∙+(type)className...(在这里
className
不包括任何前缀)
Objective-C框架的某些类定义了类工厂方法,这些方法与这些类的初始化程序相对应。
例如,NSString
声明了以下两个方法:
-(id)initWithFormat:
(NSString*)format,...;
+(id)stringWithFormat:
以下是您可以如何使用
NSString
这个类工厂的例子:
NSString*myString=[NSStringstringWithFormat:
@"
Customer:
%@"
self.record.customerName];
管理对象图以避免内存泄漏
Objective-C程序中的对象可构成对象图:
即通过每个对象与其他对象的关系,或对其他对象的引用,而构成的一个对象网络。
对象具有的引用可以是一对一或一对多(通过集对象)。
对象图很重要,因为它是对象存在多久的一个要素。
编译器检查对象图中的引用强度,并在合适的地方添加保留和释放消息。
注:
最近的Objective-C运行时版本实现了自动引用计数(AutomaticReferenceCounting,ARC)。
ARC使显式内存管理(也就是说,保留和释放对象)变得不再必要。
您应该经常在新应用程序项目中使用ARC,这也是默认的做法。
您通过基本C和Objective-C结构(如全局变量、实例变量和局部变量)在对象之间形成引用。
其中每个结构都附带有隐含的作用范围;
例如,被局部变量引用的对象的作用范围,正是声明它的函数块。
同样重要的是,对象之间的引用还有强弱之分。
强引用表示从属关系;
引用对象拥有被引用的对象。
弱引用则暗示引用对象不拥有被引用的对象。
一个对象的寿命是由它被强引用多少次来决定的。
只要对象还存在强引用,就不会释放该对象。
默认情况下,Objective-C中的引用是强引用。
这通常是件好事,让编译器能够管理对象的运行时长,这样对象就不会在您使用时被释放。
但是,一不小心,对象之间的强引用会形成一个不能断开的引用链,如下图左侧所示。
这种不间断链可以导致运行时不释放任何对象,因为每个对象都具有强引用。
结果,强引用循环可导致程序发生内存泄漏。
对于图中的对象,如果断开A和B之间的引用,则包含B、C、D和E的子图形将“永远”存在,因为这些对象通过强引用循环绑定在一起。
通过引入E至B的弱引用,您断开了此强引用循环。
对强引用循环的解决之道,在于明智地使用弱引用。
运行时同时跟踪对象的弱引用和强引用。
一个对象未被强引用时,该对象将被释放,对该对象的所有弱引用都会设定为
对于变量(全局、实例和局部),请在变量名称前面使用
__weak
限定符,以将引用标记为弱。
有关属性,请使用weak选项。
您应该将弱引用用于以下种类的引用:
∙委托
@property(weak)iddelegate;
∙您将在“设计模式”文章“采用设计模式使您的应用程序合理化”中了解有关委托和目标的信息。
∙未引用顶级对象的Outlet
@property(weak)IBOutletNSString*theName;
∙Outlet是对象之间的连接(或引用),归档在串联图或nib文件中,且在应用程序载入该串联图或nib文件时得到恢复。
串联图或nib文件中顶级对象(通常是窗口、视图、视图控制器或其他控制器)的outlet应该为
strong(默认值,因此无标记)。
∙目标
(void)setTarget:
(id__weak)target
∙在块内对
self
的引用
__blocktypeof(self)tmpSelf=self;
[selfmethodThatTakesABlock:
^{
[tmpSelfdoSomething];
}];
∙一个块对它所捕捉的变量构成强引用。
如果在块内使用
self,该块对
构成强引用。
因此,如果
也具有对该块的强引用(通常都有),将产生强引用循环。
要避免循环,您需要在块外创建对
的
weak(或
__block)引用,如以上例子所示。
对象可变性的管理
可变对象是指在创建后,可以更改其状态的对象。
您通常通过属性或存取方法进行更改。
不可变对象是指在创建后,不可以更改其封装状态的对象。
您从Objective-C框架的大多数类所创建的实例是可变的,还有少数是不可变的。
不可变对象具有以下好处:
∙不可变对象被使用时,其值不会意外更改。
∙对于许多对象而言,如果不可变,可提高其应用性能。
在Objective-C框架中,不可变类的实例通常用来封装离散的或缓冲的一组值,如数组和字符串。
这些类通常具有可变变体,其名称包含“Mutable”。
例如,有
类(不可变)和
NSMutableString
类。
请注意,封装离散值的部分不可变对象(如
NSNumber
或NSDate)没有可变类变体。
当您期望以增量方式频繁地更改对象的内容时,应使用可变对象,而不使用不可变变体。
如果从框架接收到一个对象,其类型被定为不可变对象,请遵循该返回类型;
请勿尝试更改该对象。
创建和使用值对象
值对象是指封装了基本值(属于C数据类型)且提供与该值相关的服务的对象。
值对象以对象形式表示标量类型。
Foundation框架向您提供了以下类(这些类产生对象,用于字符串、二进制数据、日期与时间、数字以及其他值):
∙NSString
NSMutableString
∙NSData
NSMutableData
∙NSDate
∙NSNumber
∙NSValue
值对象在Objective-C编程中很重要。
您会频繁遇到这些对象,作为应用程序调用的方法和函数的参数和返回值。
通过传递值对象,同一框架的不同部分以至不同的框架都可交换数据。
因为值对象表示标量值,您可以在集(collections)中使用它们,也可以在任何需要对象的地方使用它们。
但是,对象值除这些共性和由此产生的必然性之外,它们在其封装的基本类型上还具有另一项优势:
它们让您能采用简单但高效的方式,对封装的值执行某些操作。
类具有用于搜索和替换子字符串、将字符串写入文件或(首选)URL以及构建文件系统路径的方法。
有时,使用基本类型(即类型为
int(整型)、float
等的值)更高效、更直接。
这种情况的一个主要例子是计算数值。
因此,NSNumber
NSValue
对象在框架方法中,较少用作参数和返回值。
但是,许多框架声明了它们自己的数值数据类型,并将这些类型用于参数和返回值;
例如
NSInteger
CGFloat。
您应该在合适的地方使用框架定义的这些类型,因为它们有助于让您的代码不拘泥于底层平台。
使用值对象的基本知识
创建值对象的基本模式,是让您的代码或框架代码从基本类型的数据创建值对象(接着也许在一个方法参数中传递它)。
在您的代码中,稍后会从该对象访问被封装的数据。
类提供了此方法的最清晰示例:
intn=5;
//Valueassignedtoprimitivetype
NSNumber*numberObject=[NSNumbernumberWithInt:
n];
//Valueobjectcreatedfromprimitivetype
inty=[numberObjectintValue];
//Encapsulatedvalueobtainedfromvalueobject(y==n)
大多数“值”类同时声明初始化程序和类工厂方法来创建实例。
某些类(特别是
NSData)还提供初始化程序和类工厂方法,来根据储存在本地或远程文件中的基本数据以及内存中的数据创建实例。
这些类还提供补充方法,来将字符串和二进制数据写入文件或URL指定的位置。
以下示例中的代码调用
initWithContentsOfURL:
方法,根据URL对象定位到的文件的内容,创建
NSData
对象;
使用数据后,代码会将数据对象写回文件系统:
NSURL*theURL=//CodethatcreatesafileURLfromastringpath...
NSData*theData=[[NSDataalloc]initWithContentsOfURL:
theURL];
//usetheData...
[theDatawriteToURL:
theURLatomically:
除创建值对象和让您访问其封装值之外,大多数值类都提供用于简单操作(如对象比较)的方法。
将值类的实例声明为属性时,应该使用
copy
选项。
字符串和NSString字面常量
作为C的超集,Objective-C支持的、用于指定字符串的约定与C相同:
单个字符使用单引号括起来,字符串则使用双引号括起来。
但是,Objective-C框架通常不使用C字符串。
相反,它们使用
对象。
在您的首个iOS应用程序中创建
HelloWorld
应用程序时,创建了一个格式化字符串:
NSString*greeting=[[NSStringalloc]initWithFormat:
Hello,%@!
"
nameString];
类为字符串提供对象包装器,这提供了很多便利,如内建内存管理用于储存任意长度的字符串、支持各种字符编码(特别是Unicode),以及提供了
printf
样式的格式化实用工具。
因为您通常使用这样的字符串,所以Objective-C提供速写记法来根据常量值创建
要使用此
字面常量,只需在普通双引号字符串前面添加
@
符号,如下例所示:
//Createthestring"
MyString"
pluscarriagereturn.
NSString*myString=@"
MyString\n"
;
//Createtheformattedstring"
1String"
.
NSString*anotherString=[NSStringstringWithFormat:
%d%@"
1,@"
String"
];
//CreateanObjective-CstringfromaCstring.
NSString*fromCString=[NSStringstringWithCString:
ACstring"
encoding:
NSASCIIStringEncoding];
NSNumber字面常量
Objective-C还提供速写记法来创建
对象,从而无需调用初始化程序或类工厂方法,来创建此类对象。
只需在数值前面添加@
符号,并可选择在后面添加一个值类型指示。
例如,要创建封装一个整数值和一个双精度值的
对象,您可以编写以下代码:
NSNumber*myIntValue
=@32;
NSNumber*myDoubleValue=@3.22346432;
您甚至可以使用
字面常量,创建封装的Boolean值和字符值。
NSNumber*myBoolValue=@YES;
NSNumber*myCharValue=@'
V'
您可以创建
对象,表示无符号整型(unsignedintegers)、长整型(longintegers)、长长整型(longlongintegers)和浮点值(floatvalues),方法是将字符“U”、“L”、“LL”和“F”分别追加到记号值末尾。
例如,要创建一个
封装一个浮点值,您可以编写以下代码:
NSNumber*myFloatValue=@3.2F
日期和时间
NSDate
对象与其他种类的值对象不同,这是因为以时间作为基本值的独特性质。
日期对象封装自参考日期算起的时间间隔(以秒为单位)。
该参考日期是GMT2001年1月1日开始的那一刻。
仅通过
的实例本身,您无法做些什么。
它的确表示某个时刻,但这种表示方式没有由一个区域的日历、时区和时间约定所提供的关联。
幸运的是,有一些Foundation类可以表示这些概念性实体:
∙NSCalendar
NSDateComponents——您可以将日期与日历关联,然后从该日期的日历派生时间单位,如年、月、小时和星期几。
您还可以执行日历运算。
∙NSTimeZone——在日期和时间必须反映某个区域的时区时,可以将时区对象与日历关联。
∙NSLocale——区域对象封装了文化和语言约定,包括与时间相关的那些约定。
以下代码片段说明了如何将
对象与其他此类对象配合使用,以获取您想要的信息(在本示例中,当前时间按照小时、分钟和秒数打印出来)。
NSDate*now=[NSDatedate];
//1
NSCalendar*calendar=[[NSCalendaralloc]initWithCalendarIdentifier:
NSGregorianCalendar];
//2
[calendarsetTimeZone:
[NSTimeZonesystemTimeZone]];
//3
NSDateComponents*dc=[calendarcomponents:
(NSHourCalendarUnit|NSMinuteCalendarUnit|
NSSecondCalendarUnit)fromDate:
now];
//4
NSLog(@"
Thetimeis%d:
%d:
%d"
[dchour],[dcminute],[dcsecond]);
//5
本列表解释代码的每个编号行:
1.创建表示当前时刻的日期对象
2.创建表示公历的对象
3.使用表示时区(在“系统偏好设置”中指定的时区)的对象设定日历对象。
4.在日历对象上调用
components:
fromDate:
方法,传入在步骤1中已创建的日期对象。
此调用返回一个对象,该对象包含该日期对象的小时、分钟和秒数分量。
5.将当前小时、分钟和秒数记录到控制台
尽管此示例记录了结果,但在应用程序用户界面上显示日期信息的首选方法,是使用日期格式化程序(NSDateFormatter
类的实例)。
您应该经常将合适的类和方法用于日历计算;
对于分钟、小时和天等单位,请勿对数值进行硬编码。
创建和使用集
集(collection)是一个对象,它以特定方式储存其他对象,并且允许客户端访问那些对象。
您通常将集作为方法和函数的参数进行传递,且通常获取集作为方法和函数的返回值。
集经常包含值对象,但可以包含任何类型的对象。
大多数集都具有对其包含的对象的强引用。
Foundation框架有几种类型的集,但其中有三种在CocoaTouch和Cocoa编程中尤其重要:
数组(array)、字典(dictionary)和集合(set)。
这些集的类具有不可变变体和可变变体。
可变集允许您添加和移除对象,而不可变集仅可包含用来创建该集的那些对象。
所有集都允许您枚举其内容——换言之,允许您依次检查它所包含的每个对象。
不同类型的集采用不同的方式组织它们所包含的对象:
∙NSArray
NSMutableArray——数组是多个对象的有序集。
通过在数组中指定对象的位置(即索引)来访问对象。
数组中首个元素的索引是0(零)。
∙NSDictionary
NSMutableDictionary——字典将其条目储存为键-值对;
键是一个唯一标识符,通常是字符串,而值则是您要储存的对象。
通过指定键,您可以访问该对象。
∙NSSet
NSMutableSet——集合储存一组无序对象,其中每个
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 05 ios 开发 指南 基础 基本 任务
![提示](https://static.bdocx.com/images/bang_tan.gif)