当你着手为你的应用编写代码的时候,你会发现有许多可供使用的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. 李洪强iOS开发之宏定义方法来初始化一个单例对象

    单例的使用: .m 为了方便实用,只要将以下代码定义在header文件或者.pch文件即可: // .h #define singleton_interface(class) + (instancet ...

  2. [Unity菜鸟] 摄像机视角控制

    1. 摄像机预览物体 上下左右远近 把CameraFollow脚本赋给Camera,把要观察的对象赋给target using UnityEngine; using System.Collection ...

  3. matlab 中保存某几个变量

    save  AOA.mat dingjiao RMSE%保存变量dingjiao,RMSE于AOA.mat clear all;%当删除所有数据之后 load AOA.mat%还可以读出这两个变量的数 ...

  4. netty 实现socket服务端编写

    import java.net.InetSocketAddress; import io.netty.bootstrap.ServerBootstrap; import io.netty.channe ...

  5. Jquery attr()方法 属性赋值和属性获取

    jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. 1. attr(属性名 ...

  6. VPN DNS leak 问题的解决

    前一段时间遇到一个问题.customer说发现连接VPN后在PPP端发现security leak,整个转了好大一个圈子才把问题解决了.之所以费这么大周折,倒不是因为很难解决,只是费了很大劲儿才定位了 ...

  7. 使用net start mysql的时候出现服务名无效的原因及解决办法

    原因:mysql服务没有安装 解决办法:使用管理员权限,执行mysqld -install命令 然后以管理员身份net start mysql开启mysql服务 卸载mysql服务的方法 1.管理员权 ...

  8. Angularjs中input的指令和属性

    建议添加 novalidate属性(可无值)到form标签上,这样可以保证在表单不合法的情况下阻止浏览器继续提交数据. 可以给表单元素 input 添加 required 属性(可无值),让该表单成为 ...

  9. poj2482Stars in Your Window(线段树+离散化+扫描线)

    http://poj.org/problem?id=2482 类似于上一篇 这题转化的比较巧妙 将一个点转化为一个矩形(x,y, x+w,y+h),扫描线入值为正 出值为负 也就是一根线过去 每进入一 ...

  10. 函数buf_LRU_free_from_unzip_LRU_list

    /******************************************************************//** Try to free an uncompressed ...