当你着手为你的应用编写代码的时候,你会发现有许多可供使用的Objective-C的框架类,其中尤其重要的就是基础框架类,它为平台所有的应用提供基础服务。基础框架类中包括了表示字符串和数字等基本数据类型的值类(value classes),也有用来存储其他对象的集合类(collection classes)。你将会依赖值类和集合类为你的ToDoList app编写大量代码。

值对象(Value Objects)
 
Foundation框架提供了生成字符串、二进制数据、日期和时间、数字以及其他值对象的类。
 
值对象封装了C语言中的基本数据类型,并提供针对相应数据类型操作的方法。在程序调用中,你会经常遇到将值对象作为参数或返回值的方法和函数。框架中的不同部分,乃至不同框架之间都可以通过值对象类传递数据。
 
Foundation框架中值对象的例子:
• NSString and NSMutableString 
• NSData and NSMutableData 
• NSDate 
• NSNumber 
• NSValue 
 
因为值对象代表的是标量值,你可以在集合类和其他任何需要的类中使用它们。相比它封装的基元数据,值对象可以让你更简单高效地操作它封装的值。以NSString类为例,它包含了查找替换子字符串、把字符串写入文件或URL、利用字符串构建文件系统路径等方法。
 
你可以用基元数据创建一个值对象(如果有必要的话,将其作为参数传递给某一方法),之后就可以通过该对象来访问被封装的数据。下面以NSNumber类来演示说明以上创建值对象的方法。
  1. int n = 5; // Value assigned to primitive type
  2. NSNumber *numberObject = [NSNumber numberWithInt:n]; // Value object created from primitive type
  3. int y = [numberObject intValue]; // Encapsulated value obtained from value object (y == n)
 
大多数值类通过声明初始化器和类工厂方法来创建它们的实例。类工厂方法可以完成实例的分配和初始化,返回一个被创建的对象。例如,NSString类声明了一个string类方法,可以分配并初始化该类的一个新实例,并作为返回值返回给你的代码使用。
  1. NSString *string = [NSString string];
 除了创建值对象,并让你访问它们封装的值,多数值类都提供了诸如对象比较之类的简单操作方法。
 
字符串
Objective-C支持同C语言一样的惯例来指定字符串:通过单引号表示单个字符,双引号表示字符串,但是Objective-C框架一般不使用C字符串,它们通常使用NSString对象。
 
NSString类提供了一个字符串的封装,具有以下优势:内置内存管理功能可以存储任意长度的字符串、支持不同的字符编码(尤其是Unicode)以及字符格式化的方法。因为你常常会用到这样的字符串,所以Objective-C提供了一种从常量值创建NSString对象的简便方法。想要使用该常量,可在字符串的双引号前面加一个@符号即可,如下例所示。
  1. // Create the string "My String" plus carriage return.
  2. NSString *myString = @"My String\n";
  3. // Create the formatted string "1 String".
  4. NSString *anotherString = [NSString stringWithFormat:@"%d %@", 1, @"String"];
  5. // Create an Objective-C string from a C string.
  6. NSString *fromCString = [NSString stringWithCString:"A C string" encoding:NSUTF8StringEncoding];
 
数字
Objective-C为创建NSNumber对象的提供了简化符号,除去了调用初始化器或者类工厂方法创建这些对象的需要。只需简单地在数值前面加@符号即可,你还可以在数值之后加一个类型指示符。比如,想要创建一个封装了整数值和双精度值的NSNumber对象,你需要编写如下代码:
  1. NSNumber *myIntValue    = @32;
  2. NSNumber *myDoubleValue = @3.22346432;
你甚至可以使用NSNumber常量来创建封装布尔类型和字符类型的对象,如下所示:
  1. NSNumber *myBoolValue = @YES;
  2. NSNumber *myCharValue = @'V';
你可以通过U、L、LL、和F后缀来创建分别代表无符号整型、长整型、超长整型和浮点类型的NSNumber对象。如下代码示例创建了一个封装了浮点值类型的NSNUmber对象:
  1. NSNumber *myFloatValue = @3.2F;
 
集合对象
 
Objective-C中的大部分集合对象都是NSArray、NSSet和NSDictionary这些基本集合类的实例。这些类用来管理群组对象,所以你添加到集合中的实例必须为一个Objective-C类。如果你需要添加标量数值,你必须创建一个合适的NSNumber或NSValue实例来代表它。
 
在集合被销毁前,集合中存储的成员对象不能被销毁。这是因为集合类采用强引用来维护它的成员对象。除了跟踪维护它对象外,集合类还提供枚举、访问特定对象、判断某一对象是否在集合内等功能。
 
NSArray, NSSet和 NSDictionary类的内容在集合创建时即被初始化,之后在使用中不能再被改变,这种类叫不可变类。每一个集合类都有一个可变的子类允许你随意添加删除成员对象。不同集合类组织它们成员对象的方式是不同的:
• NSArray和NSMutableArray—存储有序对象的数组。你可以通过在数组中指定位置来访问一个成员对象。数组中第一个元素的索引为0。
• NSSet和NSMutebleSet—存储无序对象的集合。每个元素在集合中具有唯一性。你只能通过测试或筛选的方法来访问集合中的对象。
• NSDictionary和NSMutableDictionary—通过键值对存储的一个词典。键是一个独特的标识符,通常是一个字符串,值就是你想要存储的对象。你可以通过指定键来访问该对象。
 
数组
数组(NSArray)用来表示一组有序对象,唯一的要求是每个对象必须是一个Objective-C对象,至于每个对象是不是同一个类的实例没有要求。
 
为了维护数组的有序性,元素的索引从0开始,如下图所示:
创建数组
与本章前面介绍的值类相同,你可以通过分配和初始化、工厂方法或者数组常量来创建一个数组。根据对象个数的不同,有很多初始化和工厂方法可供使用:
  1. + (id)arrayWithObject:(id)anObject;
  2. + (id)arrayWithObjects:(id)firstObject, ...;
  3. - (id)initWithObjects:(id)firstObject, ...;
由于arrayWithObjects:和initWithObjects:方法都是可变参数长度并以nil结束,初始化如下代码所示:
  1. NSArray *someArray =
  2. [NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil];
上例创建了一个与之前类似的数组,其中第一个对象someObject的索引值是0,最后一个对象someValue的索引值是3。
 
如果中间某一个值是nil,数组可能会被截断。
  1. id firstObject = @"someString";
  2. id secondObject = nil;
  3. id thirdObject = @"anotherString";
  4. NSArray *someArray =
  5. [NSArray arrayWithObjects:firstObject, secondObject, thirdObject, nil];
本例中,someArray只包含firstObject,因为secondObject的值是nil,因此被当作数组的结束符。
 
可以使用如下简便的语法来创建一个数组常量:
  1. NSArray *someArray = @[firstObject, secondObject, thirdObject];
当使用这个语法是,不要用nil来结束对象列表,实际上,nil是一个不存在的值。例如,你在执行以下代码时会得到一个运行异常:
  1. id firstObject = @"someString";
  2. id secondObject = nil;
  3. NSArray *someArray = @[firstObject, secondObject];
  4. // exception: "attempt to insert nil object"
 
 查询数组对象
创建完数组之后,你可以查询其中个的信息,比如它包含多少对象,或它是否包含某一给定对象。
  1. NSUInteger numberOfItems = [someArray count];
  2. if ([someArray containsObject:someString]) {
  3. ...
  4. }
你还可以通过一个给定的索引来查询数组的项目,如果尝试请求一个不存在的索引,那么运行时你将得到一个越界异常。为了防止异常,在使用前请首先检查数组中项目的个数。
  1. if ([someArray count] > 0) {
  2. NSLog(@"First item is: %@", [someArray objectAtIndex:0]);
  3. }
本例子检查了对象个数是否大于零,如果是,Foundation框架函数NSLog输出一个数组中第一个元素的说明,它的索引为0。
 
另外一种方法是使用objecAtIndex,你还可以像C语言那样,使用方括号语法查询数组元素,上一个例子还可以写成这样:
  1. if ([someArray count] > 0) {
  2. NSLog(@"First item is: %@", someArray[0]);
  3. }
 
数组对象排序 
NSArray类为对象排序提供了一系列方法。因为NSArray是不可变的,因此这些方法会返回一个包含排序后对象的新数组。
 
例如,你可以通过对每个字符串调用compare:方法来排序字符串数组:
  1. NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];
  2. NSArray *sortedStrings =
  3. [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];
 
可变性
尽管NSArray类本身是不可变的,但是它可以包含可变对象,例如,你可以在不可变数组中添加一个可变字符串,如下所示:
  1. NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
  2. NSArray *immutableArray = @[mutableString];
于是你可以随意改变字符串的内容。
  1. if ([immutableArray count] > 0) {
  2. id string = immutableArray[0];
  3. if ([string isKindOfClass:[NSMutableString class]]) {
  4. [string appendString:@" World!"];
  5. }
  6. }
如果想在数组创建后添加或删除数组中的对象,你可以使用NSMutableArray,该类添加了一系列方法来添加删除、替换一个或多个对象。
  1. NSMutableArray *mutableArray = [NSMutableArray array];
  2. [mutableArray addObject:@"gamma"];
  3. [mutableArray addObject:@"alpha"];
  4. [mutableArray addObject:@"beta"];
  5. [mutableArray replaceObjectAtIndex:0 withObject:@"epsilon"];
本示例创建了一个由对象@"epsilon", @"alpha"和 @"beta"组成的数组。对于可变数组,你可以在不生成新数组的情况下对数组进行排序,如下所示:
  1. [mutableArray sortUsingSelector:@selector(caseInsensitiveCompare:)];
本例中,数组元素按升序排列,不区分大小写。
 
集对象与数组类似,但是它包含的是无序互异对象。
由于集是无序的,因此在测试成员对象时性能比数组要好。集是不可变的,因此它的内容必须在创建时指定。
  1. NSSet *simpleSet =
  2. [NSSet setWithObjects:@"Hello, World!", @42, aValue, anObject, nil];
同NSArray类一样,initWithObjects:和setWithObjects:方法是可变长度的参数,必须以nil结束。NSSet的可变子类是NSMutableSet。
 
每个对象集只存储一次,即使你不止一次添加一个对象。
  1. NSNumber *number = @42;
  2. NSSet *numberSet =
  3. [NSSet setWithObjects:number, number, number, number, nil];
  4. // numberSet only contains one object
 
词典
与简单的维护一个有序或无序的集合对象不同,词典(NSDictionary)使用给定键值对存取对象,它可以被用于检索。通常使用字符串对象作为字典的键。
尽管你可以使用其他对象作为键,但是请记住每个键是被复制到字典中的,因此该对象必须支持NSCopying方法。然而,如果你想要使用键值对编码,你必须使用string key作为词典对象(详情请参见Key-Value Coding Programming Guide)。
 
创建词典
你可以使用alloc和初始化,或类的工厂方法来创建词典,如下所示:
  1. NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
  2. someObject, @"anObject",
  3. @"Hello, World!", @"helloString",
  4. @42, @"magicNumber",
  5. someValue, @"aValue",
  6. nil];
对于 dictionaryWithObjectsAndKeys: 和 initWithObjectsAndKeys: 方法,每个对象必须在键前面声明,并以nil结束。 
 
Objective-C为词典常量创建提供了简便语法: 
  1. NSDictionary *dictionary = @{
  2. @"anObject" : someObject,
  3. @"helloString" : @"Hello, World!",
  4. @"magicNumber" : @42,
  5. @"aValue" : someValue
  6. };
对于字典常量,键在对象前指定,并且列表对象和键无需以nil结束。
 
查询词典
创建词典之后,你可以查询键对应的对象,如下所示:
  1. NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];
如果对象未找到, objectForKey: 方法会返回 nil. 
 
除了objectForKey:方法,你还可以使用如下方法进行查询: 
  1. NSNumber *storedNumber = dictionary[@"magicNumber"];
 
可变性
如果你需要在词典创建后添加或者删除内容,请使用NSMutableDictionary 类。
  1. [dictionary setObject:@"another string" forKey:@"secondString"];
  2. [dictionary removeObjectForKey:@"anObject"];
 
使用 NSNull表示nil
你不能将nil添加到本节描述的集合类中,因为nil在Objective-C 中代表“不存在的对象”,如果你需要在集合中表示一个不存在的对象,请使用NSNull类。
  1. NSArray *array = @[ @"string", @42, [NSNull null] ];
在NSNull中,null方法总是返回同一个实例,具有这样行为的类被称为“骨架类”( singleton classes)。你可以使用以下方法检查一个对象是否等于NSNull:
  1. for (id object in array) {
  2. if (object == [NSNull null]) {
  3. NSLog(@"Found a null object");
  4. }
  5. }
尽管Foundation框架包含的功能比此处描述的要多很多,但你不需要现在就掌握其每一个细节。如果你想要了解更多Foundation框架知识,请参看Foundation Framework Reference。目前你已掌握足够的信息来继续实现ToDoList这个应用,为了实现它你需要写一个自定义数据类。

ios 对象的集合类(collection classes)的更多相关文章

  1. 12. 集合类Collection和Map

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  2. 集合框架的类和接口均在java.util包中。 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。

    集合框架的类和接口均在java.util包中. 任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换.

  3. Pop–实现任意iOS对象的任意属性的动态变化

    简介 Pop 是一个可扩展的动画引擎,可用于实现任意iOS对象的任意属性的动态变化,支持一般动画,弹性动画和渐变动画三种类型. 项目主页: pop 最新示例: 点击下载 注意: 官方代码中,并不包含实 ...

  4. 第十节 集合类Collection和Map

    接口 Collection<E>  (E)代表类型 集合类: 与数组的异同: 数组:数组虽然也可以存储对象,但长度是固定的:集合的长度是可变的,数组中可以存储基本数据类型,集合只能存储对象 ...

  5. 集合类 collection接口 ArrayList

    数组: 存储同一种数据类型的集合容器.数组的特点:1. 只能存储同一种数据类型的数据.2. 一旦初始化,长度固定. 3. 数组中的元素与元素之间的内存地址是连续的. : Object类型的数组可以存储 ...

  6. 集合类——Collection、List、Set接口

    集合类 Java类集 我们知道数组最大的缺陷就是:长度固定.从jdk1.2开始为了解决数组长度固定的问题,就提供了动态对象数组实现框架--Java类集框架.Java集合类框架其实就是Java针对于数据 ...

  7. 集合类 Collection

    1.Collection接口有两个子接口: List:保存元素顺序的线性表,允许有重复元素. Set:不记录元素的保存顺序,不允许有重复元素.数学中的集合 Collection接口中的方法如下: Co ...

  8. Why do collection classes appear

    package com.itheima_01; import java.util.ArrayList; /* * 为什么会出现集合类: * 我们学习的是面向对象编程语言,而面向对象编程语言对事物的描述 ...

  9. 集合类Collection Map

    数组与集合的区别:数组虽然也可以存储对象,但长度是固定的:集合的长度是可变的,数组中可以存储基本数据类型,集合只能存储对象. 集合特点:1.用于存储对象:  2.长度可变: 3.可存储不同对象: 一. ...

随机推荐

  1. <context:component-scan>配置解析(转)

    在xml配置了这个标签后,spring可以自动去扫描base-pack下和其子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注 ...

  2. PHP基础语法2

    数组 PHP有两种数组:索引数组.关联数组. 函数 自定义函数 自定义函数通过将一组代码封装起来,使代码进行复用,程序结构与逻辑更加清晰 返回值 使用return关键字可以使函数返回值,可以返回包括数 ...

  3. Mysql一主多从和读写分离配置简记

    近期开发的系统中使用MySQL作为数据库,由于数据涉及到Money,所以不得不慎重.同时,用户对最大访问量也提出了要求.为了避免Mysql成为性能瓶颈并具备很好的容错能力,特此实现主从热备和读写分离. ...

  4. 173. Binary Search Tree Iterator

    题目: Implement an iterator over a binary search tree (BST). Your iterator will be initialized with th ...

  5. Android安全问题 钓鱼程序

    导读:文本介绍一种钓鱼应用,讲述如何骗取用户的用户名和密码,无须root 这个话题是继续android安全问题(二) 程序锁延伸的 之前我已经展示了如何制作程序锁.当打开指定应用的时候,弹出一个密码页 ...

  6. 编译GNU Global

    GNU Global是一套界面更友好的tag系统,但是因为其支持的语言太少,现在一般使用其为前端,后端一般使用最新的Universal Ctags. 编译办法如下: 1.去GNU Project ht ...

  7. jekyll themes

    jekyll主题下载: https://mademistakes.com/work/jekyll-themes/ https://github.com/jekyll/jekyll/wiki/Theme ...

  8. poj 1442 Black Box(堆 优先队列)

    题目:http://poj.org/problem?id=1442 题意:n,m,分别是a数组,u数组的个数,u[i]w为几,就加到a几,然后输出第i 小的 刚开始用了一个小顶堆,超时,后来看了看别人 ...

  9. ListView中使用type需要注意的东西 java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 addScrapView

    ListView中使用type需要注意的东西 在使用ListView时,如果使用了getItemViewType, 记得他的值一定要是从0开始计数的. 且要覆盖getViewTypeCount方法.并 ...

  10. The only legal comparisons are between two numbers, two strings, or two dates.

    The only legal comparisons are between two numbers, two strings, or two dates. Left  hand operand is ...