(译)Getting Started——1.3.3 Working with Foundation(使用Foundation框架)
在你使用Objective-C语言开发应用时,你会发现在开发中,你会用到很多框架。尤其是Foundation框架,该框架为应用提供了最基础的服务。Foundation框架包括了代表着基本数据类型的value类,例如字符串,数值,它也包括了用于存储其它对象的collection类。在ToDoList应用中,你将应用value和collection类来编写代码。
value类
Foundation框架提供了用于生成字符类型、二进行类型、时间类型、数字类型、其它类型的工具类。
value对象封装了一个原始值(C数据类型),并提供该值的相关服务。在应用中,当你调用方法时,你经常会遇到value对象,比如方法的参数,或返回值。框架的不同部分——甚至不同的框架——之间,都可以通过传递这些value对象来完成数据交换的目的。
在Foundation框架中value对象的部分示例:
NSString,NSMutableString
NSData,NSMutableData
NSDate
NSNumber
NSValue
因为value对象代表了标量值,因此,你可以在集合或其它对象需要的任何地方,都可以使用它们。value对象优于由它们封装的基本类型:它们让你在基于封装的值上进行的操作变得简单和有效。例如,NSString类有搜索字符串和替换子串的方法,有给文件或URL添加字符串的方法,还有构建文件系统路径的方法。
你可以利用基本类型来创建value对象。例如,NSNumber就提供了类似的方法:
int n = 5; // Value assigned to primitive type
NSNumber *numberObject = [NSNumber numberWithInt:n]; // Value object created from primitive type
随后,你可以获取到包装到对象里的数据:
int y = [numberObject intValue]; // Encapsulated value obtained from value object (y == n)
大多数的value类通过初始化或类构建方法的方式来申明它们的实例。类构造方法——由类来实现,作为客户端的约定——把分配和初始化结合在一起,最后返回要创建的对象。例如,NSString类申明了一个返回类型为string的类方法,它已经申请和实例化了一个新的类实例。
NSString *string = [NSString string];
除了创建value对象和获取被封装的值,大多数的value类都提供了简化操作的方法,例如,对象比较等。
字符串
对于字符串来说,Objective-C和C支持相同的约定:单个字符用单引号,多个字符用双引号。但是,Objective-C框架不使用C字符,用的是NSString对象。
NSString类提供了字符的对象包装方法,提供了内建的任意长度字符串的内存管理,提供了不同的字符编码(尤其是Unicode),还为格式化字符提供了工具集。对于使用频度很高的字符串来说,Objective-C为创建NSString对象的常量值提供了快捷的方法。要使用NSString的字面值,只要在用双引号括起的字符串前面添加@就可以了,如下所示:
// Create the string "My String" plus newline.
NSString *myString = @"My String\n";
// Create the formatted string "1 String".
NSString *anotherString = [NSString stringWithFormat:@"%d %@", 1, @"String"];
// Create an Objective-C string from a C string.
NSString *fromCString = [NSString stringWithCString:"A C string" encoding:NSUTF8StringEncoding];
数值
Objective-C提供了快捷的创建NSNumber对象的方法,不需要调用初始化或类的构建方法就可以创建NSNumber对象。只要在数字前面添加@符号就行。例如,你可以这样创建整形或双精度类型的对象:
NSNumber *myIntValue = @32;
NSNumber *myDoubleValue = @3.22346432;
你甚至可以使用Boolean类型和字符类型的值来创建NSNumber对象:
NSNumber *myBoolValue = @YES;
NSNumber *myCharValue = @'V';
你可以创建NSNumber来表示unsigned integers,long integers,long long integers和float values,只需要在数字后相应添加U,L,LL和F。例如,要创建一个浮点类型的值,你可以这样:
NSNumber *myFloatValue = @3.2F;
集合对象
Objective-C中的大多数集合对象都是基本集合类:NSArray、NSSet和NSDictionary类的实例。集合类的被用来管理一组对象,因此,给集合添加的任一元素都必须是Objective-C类的实例。如果你需要给集合添加数字值,你必须先把它转换为合适的NSNumber或NSValue类型的对象,然后再把对象添加到集合中。
只要集合存在,集合中的任一对象都存在,这是因为集合类在保存集合内的元素时,使用的是强引用。除了保存集合内元素的强引用之外,每个集合类还有一些便于某些特殊任务操作的执行方法,例如,枚举,获取特定元素,找出某个对象是否是集合的一部分等等。
NSArray、NSSet和NSDictionary类的内容是集合。因为随着时间的推移,它们的内容不能发生变化,因此,这些类被称为不可变的。这三个类都有可变化的子类,这些子类可以随时添加或删除对象。不同类型的集合以独特的方式组织集合内的对象:
NSArray和NSMutableArray:这两种数组中的对象都是有序的。可以通过位置(即索引)获取数组中的对象。数组中的首个元素的索引是0。
NSSet和NSMutableSet:存储无序对象的集合,集合中的对象不重复。在该类集合中,一般使用测试或过滤的方式来获取元素。
NSDictionary和NSMutableDictionary:字典中存储的是键值对实体。键是实体的唯一标识,一般是字符串类型,值是对象类型。通过键值来获取数据。
Array
数组代表了有序对象的集合。唯一的要求是数组中的每个元素都必须是Objective-C中的对象类型——数组中每个元素的类型可以不一样。
为了维持数组的有序性,数组里的元素都有索引来标识,索引是从0开始的。
创建数组
通过初始化或类构造方法来创建数组。有一系列不同的初始化和类构造方法可以使用,具体使用哪个方法依赖于对象的数量:
+ (id)arrayWithObject:(id)anObject;
+ (id)arrayWithObjects:(id)firstObject, ...;
- (id)initWithObjects:(id)firstObject, ...;
因为arrayWithObjects和initWithObjects方法都以nil作为参数的中止,因此,必须包含nil:
id firstObject = @"someString";
id secondObject = @"secondString";
id thirdObject = @"anotherString";
NSArray *someArray =
[NSArray arrayWithObjects:firstObject, secondObject, thirdObject, nil];
上面的例子中,使用三个对象创建了一个数组。第一个元素:firstObject的索引是0;最后一个对象:thirdObject的索引是2.
也可以使用紧凑的语法来创建数组:
NSArray *someArray = @[firstObject, secondObject, thirdObject];
在使用紧凑的语法创建数组时,最后一个元素不能是nil——事实上,nil是个无用的值。例如,如果你执行下面的代码,那么在运行时,你会获得一个异常:
id nilObject = nil;
NSArray *someArray = @[firstObject, nilObject];
// exception: "attempt to insert nil object"
查询数组对象
数组被创建后,你可以对数组进行查询——例如,数组中的元素个数,或者数组中是否包含某个元素等。
NSUInteger numberOfItems = [someArray count];
if ([someArray containsObject:secondObject]) {
...
}
你还可以使用索引来查询数组元素。如果你尝试使用一个不存在的索引来查询数组元素,那么在运行时,你会获取数取越界的异常。为了避免这个异常,在根据索引进行查询前,应该都做个检查:
if ([someArray count] > 0) {
NSLog(@"First item is: %@", [someArray objectAtIndex:0]);
}
上面代码检查的是数组中是否有元素。如果有,Foundation框架里的NSLog类就会把索引0位置的元素打印出来。
有个方法与objectAtIndex的方法作用相同,它获取元素的方式更类似于标准C数组获取元素的方式。前面的代码可以改为下面这个样子:
if ([someArray count] > 0) {
NSLog(@"First item is: %@", someArray[0]);
}
使用数组存储对象
NSArray类提供了许多用于存储对象的方法。因为NSArray类型的数组是不可变的,因此,每个方法都以存储时的顺序返回了一个新的数组。
例如,你可以使用compare方法对数组里的字符进行分类:
NSArray *unsortedStrings = @[@"gamma", @"alpha", @"beta"];
NSArray *sortedStrings =
[unsortedStrings sortedArrayUsingSelector:@selector(compare:)];
可变数组
尽管数组类的本身是不可变的,然而,它也可以包含可变的对象。例如,你可以这样创建包含可变字符的不可变数组:
NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
NSArray *immutableArray = @[mutableString];
没有什么可以阻止你来改变字符:
if ([immutableArray count] > 0) {
id string = immutableArray[0];
if ([string isKindOfClass:[NSMutableString class]]) {
[string appendString:@" World!"];
}
}
在初始化操作后,如果你想从数组中添加或移除对象,请使用NSMutableArray类,使用该类,你可以添加、删除、替换任意数量的对象:
NSMutableArray *mutableArray = [NSMutableArray array];
[mutableArray addObject:@"gamma"];
[mutableArray addObject:@"alpha"];
[mutableArray addObject:@"beta"];
[mutableArray replaceObjectAtIndex:0 withObject:@"epsilon"];
以上的代码创建了一个由@"epsilon",@"alpha"和@"beta"三个对象构成的数组。
也可以不用创建第二个数组就对一个可变数组中的元素进行分类:
[mutableArray sortUsingSelector:@selector(caseInsensitiveCompare:)];
在上述代码的情况下,使用升序、不区分大小写的方式对数组中的元素进行了分类,结果是:@"alpha",@"beta",@"epsilon"。
Set
set(NSSet)对象与数组类似,但是它保存的是一组无序的、唯一的对象。
因为set中的元素没有顺序,因此,当在两个集合中使用测试方法时,set比array的效率高。
因为基础的NSSet类是不可变的,所以,在创建时,它里面的内容就必须被指定,创建可以使用初始化或类构造器的方法。
NSSet *simpleSet =
[NSSet setWithObjects:@"Hello, World!", @42, aValue, anObject, nil];
与NSArrary一样,initWithObjects和setWithObjects方法都需要nil参数。
在set中,即使你把同一元素添加多次,set也只会保存一次引用。
NSNumber *number = @42;
NSSet *numberSet =
[NSSet setWithObjects:number, number, number, number, nil];
// numberSet only contains one object
Dictionary
字典里的数据不是有序或无序那么简单,字典里存储的数据都有键,键可以用来检索数据。
最佳实践是使用字符串类型的键。
尽管键的类型也可以使用其它的对象类型,但是你应该明白:键是被复制使用的,因此,键必须支持NSCopying。但是,如果你想使用键-值对方式的编码,你必须为字典对象使用字符串类型的键。更多的知识可以参见Key-Value Coding Programming Guide章节。
创建字典
可以通过初始化或使用类构造方法来创建字典:
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
someObject, @"anObject",
@"Hello, World!", @"helloString",
@42, @"magicNumber",
someValue, @"aValue",
nil];
对于dictionaryWithObjectsAndKeys和initWithObjectsAndKeys这两个方法来说,先指定对象,后指定键,并且,最后以nil结尾。
Objective-C提供了创建字典的简捷语法:
NSDictionary *dictionary = @{
@"anObject" : someObject,
@"helloString" : @"Hello, World!",
@"magicNumber" : @42,
@"aValue" : someValue
};
在上面的表达式中,先指定键,后指定对象,并且,最后不以nil结尾。
查询字典
字典创建后,可以根据指定的键在字典中查询对象:
NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];
如果对象没有找到,objectForKey方法将返回nil。
有一个下标语法的功能与objectForKey方法的功能相同:
NSNumber *storedNumber = dictionary[@"magicNumber"];
可变字典
在字典创建后,如果你需要给字典添加或移除对象,那你应该使用NSMutableDictionary:
[dictionary setObject:@"another string" forKey:@"secondString"];
[dictionary removeObjectForKey:@"anObject"];
使用NSNull来表示nil
从上面的描述中就可以知道,不能在集合类中添加nil,这是因为Objective-C中nil意味着“no object”(没有对象)。你如果需要在集合中表示没有对象,请使用NSNull类:
NSArray *array = @[ @"string", @42, [NSNull null] ];
NSNull的null方法总会返回同样的实例,总会返回同样实例的类被称为单例类。你可以使用下面的方法来检查数组中的某个对象是否为NSNull类的实例:
for (id object in array) {
if (object == [NSNull null]) {
NSLog(@"Found a null object");
}
}
尽管Foundation框架里包含的能力远远多于上述描述的能力,但是,你确实不需要马上就知道每个能力的细节。如果你想学习更多foundation框架的知识,请参见Foundation Framework Reference章节。到目前为止,你已经有足够的能力来继续开发ToDoList应用了,下面章节的内容就是开发一个自定义的数据类。
(译)Getting Started——1.3.3 Working with Foundation(使用Foundation框架)的更多相关文章
- [译]MVC网站教程(一):多语言网站框架
本文简介 本博文介绍了 Visual Studio 工具生成的 ASP.NET MVC3 站点的基本框架:怎样实现网站的语言的国际化与本地化功能,从零开始实现用户身份认证机制,从零开始实现用户注册机制 ...
- 【译】Swift 字符串速查表
[译]Swift 字符串速查表 2015-12-18 10:32 编辑: suiling 分类:Swift 来源:CocoaChina翻译活动 10 5585 Swift字符串 招聘信息: iOS高级 ...
- [转] ADO.NET实体框架引发争论
转自:http://developer.51cto.com/art/200811/76356.htm 2008-11-11 14:00 朱永光译 infoq 我要评论(0) 一个在ADO.NET实体框 ...
- 【IOS】IOS高速入门之OC语法
Objective-C 是 C 语言的超集 您还能够訪问标准 C 库例程,比如在stdlib.h和stdio.h中声明的那些例程. Objective-C 还是一种很动态的程序设计语言,并且这样的动态 ...
- HTML文档类型
在HMTL5中页面的最顶端代码就是: <!DOCTYPE html> 为何要如此定义.书写呢? 首先引入一个概念:文档类型,英译为:Document type,缩写成:doctype. 文 ...
- html简单的知识
分布式版本控制git pwd查询当前目录 ls ls -la git config --global user.name xxx git config --global user. ...
- The logback manual #03# Configuration
索引 Configuration in logback Automatically configuring logback Automatic configuration with logback-t ...
- IOS-线程(GCD)
一.GCD的使用 // // IBController3.m // IBCoder1 // // Created by Bowen on 2018/4/25. // Copyright © 2018年 ...
- 用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy
目录 目录 前文列表 扩展阅读 Flask-Admin BaseView 基础管理页面 ModelView 实现效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写 ...
- iOS Hook
HOOK 译为"钩子"或挂钩.在 iOS 逆向中指改变程序运行流程的一种技术. iOS 中 hook 技术的几种方式 Method Swizzle 利用 OC 的 Runtime ...
随机推荐
- time_t和SYSTEMTIME之间的相互转换 【转】
time_t和SYSTEMTIME之间的相互转换 #include <ctime> /* **time_t转SYSTEMTIME */ SYSTEMTIME TimetToSystemTi ...
- tensorflow c++接口的编译安装与一些问题记录
参考这篇文章安装,依次安装bazel,protocbuf,eigen3,然后下载tensorflow源码,编译c++ api,将编译结果拷贝到搜索路径 最后测试案例时遇到一些问题 (1)fatal e ...
- http://www.ruanyifeng.com/blog/2013/07/gpg.html
http://www.ruanyifeng.com/blog/2013/07/gpg.html
- tomcat在ubuntu中设置开机启动
#!/bin/bash export JAVA_HOME=/usr/lib/jdk/jdk1.7.0_72 WEBROOT_PATH=/home/zhengze/workspace WEBSERVER ...
- tomcat通过虚拟路径访问外部静态资源
转载:http://blog.csdn.net/yuancenyi/article/details/53414397 在项目开发中,单个工程中,为了以后软件版本升级的方便,经常将网站运行中某些上传的静 ...
- 强大的vim配置文件,让编程更随意(转)
欢迎来到小码哥的博客 博客搬家啦 blog.ma6174.com 强大的vim配置文件,让编程更随意 花了很长时间整理的,感觉用起来很方便,共享一下. 我的vim配置主要有以下优点: 1.按F5可以直 ...
- 前端资源管理工具sourcetree
https://www.sourcetreeapp.com/
- 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)
数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...
- Python向PHP发起GET与POST请求
CloudB项目中到PHP开发WEB管理端,用Python开发服务控制端,在项目中Python的服务控制端有时候须要主动连接PHP的WEB管理端下载或上传配置參数或数据信息,这里採用的原理是Pytho ...
- Lintcode---统计比给定整数小的数的个数
给定一个整数数组 (下标由 0 到 n-1,其中 n 表示数组的规模,数值范围由 0 到 10000),以及一个 查询列表.对于每一个查询,将会给你一个整数,请你返回该数组中小于给定整数的元素的数量. ...