您的位置:首页 > 移动开发 > Objective-C

Objective-C集合

2016-03-19 17:32 591 查看
Objective-C的集合都是Cocoa 或者Cocoa Touch类。

NSArray

可以存储不同类型的对象,从零开始标号,有序数组。

1. 新建

构造方法
[NSArray arrayWithObjects:someObject, someString, someNumber,……,nil]


主要注意,最后要添加一个
nil
表示结束

使用字面量的话,不需要加
nil


NSArray *someArray = @[firstObject, secondObject, thirdObject];


如果确实要在集合中存储一个
nil
,用
NSNULL
的对象来表示,其初始化方法就是

[NSNull null]
,相当于Java中的
null


2. 访问

对象方法count返回集合中的元素个数

对象方法
containsObject:someString
可以查是否含有某字符串

像C语言数组一样的下标也可以用:比如有
NSArray *something
,可以有
something[5]


其他方法见文档

3. 排序

对象方法(1)

- (NSArray *)sortedArrayUsingSelector:(SEL)comparator;


例子

NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];
NSArray *sortedStrings = [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];


解释

这里也可以看到,
NSArray
也是不可变的,排序不能在原数组上进行,只能产生一个新的数组。就算是使用
NSMutableArray
也是一样的,因为它并没有重写其父类
NSArray
中的排序方法,在使用时调用的始终是其父类
NSArray
的排序方法。

这个方法可以让数组中的每个对象调用
compare:
方法,而方法的参数就是下一个对象,也就是说,这个
compare:
方法是实现了当前对象和下一个对象的比较,由此可以猜测这个排序方法的逻辑思路有可能就是冒泡排序法。这里
@selector(someFunction:)
会在数组元素的类定义中寻找方法
someFunction
,并且返回该方法的id(以上例子中,
NSString
类就实现了
compare:
方法,对于自定义的类也可以自定义一些用于比较的方法)。

如果用
@selector(someFunction:)
作为
- (NSArray *)sortedArrayUsingSelector:(SEL)comparator;
这个函数的参数,并运行,实际上是遍历数组并执行
[object1 someFunction:object2];``object1
object2
就是遍历的元素。

要在自定义的类中实现用于比较的方法,只要注意参数类型和返回值即可。

比如在自定义类OYContact中定义比较的方法:

-(NSComparisonResult)compareByName:(OYContact *)nextContact{
return [self.name compare:nextContact.name];
}


或者

-(NSComparisonResult)compareByAge:(OYContact *)nextOYContact{
if(_age>nextOYContact.age){
return NSOrderedAscending;
}else if(_age==nextOYContact.age){
return NSOrderedSame;
}else{
return NSOrderedDescending;
}


对象方法(2)

(NSArray*)sortedArrayUsingComparator:(NSComparator)cmptr;


解释

和上面的方法类似,但是参数直接就是比较方法的id

用法

id sortByName=^(OYContact *c1,OYContact * c2){
return [c1.name compare:c2.name];
};
contactArray=[contactArray sortedArrayUsingComparator:sortByName];


对象方法(3)

(NSArray *)sortedArrayUsingDescriptors:(NSSortDescriptor*)sortDescriptors;


解释

参数sortDescriptors是NSSortDescriptor类的对象。这个类就是排序条件,它的初始化方法如下:

‘- (instancetype)initWithKey:(NSString *)key ascending:(BOOL)ascending;`

key:按照数组中对象的哪个属性进行排序,如果数组中存放的是能够直接排序的对象(比如:字符串),直接使⽤@”self”或者nil即可;如果存放的是自定义类的对象,使用想要进行排序的属性名即可(比如:想按照Person类的name进行排序, 使用@“name”作为参数。

ascending:排序的标志,是升序还是降序。 YES - 升序, NO - 降序。

例如:

NSSortDescriptor *description=[[NSSortDescriptor alloc]initWithKey:@"name" ascending:NO];
people=[people sortedArrayUsingDescriptors:@[description]];


4. 修改

刚才说NSArray是不可变的,指的是数组中元素(对象)的位置,类型等,然而元素的内容(对象的取值)却是可以修改的。也可以理解为,NSArray对各个元素的引用不可修改,而对元素本身内容没有限制。

比如,在某个NSArray中存储了一个NSMultibleString* string对象,那么string就可以改变其内容。

当然,和很多类一样,NSArray也有一个对应的可变类型 NSMutableArray,它继承NSArray。

-NSSet

与NSArray类似,但是是无序的,互异的,即不可以存在两个相同的对象。

-NSDictionary

存储键值对key-value pair,无序的,key具有互异性。

新建

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
值, @“键”,
someObject, @“anObject”,
@“Hello, World!”, @“helloString”,
@42, @“magicNumber”,
nil ];


字面量来新建

NSDictionary *dictionary = @{
@“键” : 值,
@"anObject" : someObject,
@"helloString" : @"Hello, World!",
@"magicNumber" : @42,
@"Key" : Value
};


访问

通过key来访问值

对象方法
objectForKey:@"someKey"
,可以返回
someKey
对应的对象

如果找不到对应的key,返回
nil


通过下标的形式来访问

比如要访问上面定义的
dictionary
中的
@43
对象,可以这样表示:

NSNumber  *storedNumber=dictionary[@“magicNumber”];


修改

要修改的话还是要使用NSMutableDictionary,动态加入和删除键值对:

[dictionary setObject:@"another string" forKey:@"secondString"];


[dictionary removeObjectForKey:@"anObject"];


可以使用集合来存储自己定义的一套对象

将集合元素写入指定URL

NSURL *fileURL = ...
NSArray *array = @[@"first", @"second", @"third"];
BOOL success = [array writeToURL:fileURL atomically:YES];
if (!success) {
// an error occurred...
}


从指定URL读取集合元素

NSURL *fileURL = ...
NSArray *array = [NSArray arrayWithContentsOfURL:fileURL];
if (!array) {
// an error occurred...
}


快速枚举

C的传统做法

int count = [array count];
for (int index = 0; index < count; index++) {
id eachObject = [array objectAtIndex:index];
...
}


快速枚举的做法

for (<Type> <variable> in <collection>) {
...
}


如:

for (id eachObject in array) {
NSLog(@"Object: %@", eachObject);
}


如果是有序集合,如NSArray,每次会让下标+1。快速枚举中同样可以使用break和continue。

很多集合类本身支持快速枚举的方法

objectEnumerator
reverseObjectEnumerator
正序和倒序,用法:

for (id eachObject in [array reverseObjectEnumerator]) {
...
}


或者使用NSEnumeration类的nextObject方法

NSEnumerator *reverseEnum=[array reverseObjectEnumerator];
id element=nil;
while((element=[reverseEnum nextObject])){
//当没有元素了就会返回nil,循环结束
//以上的两个括号是必须的,如果不多加一个括号,编译器会以为你错把“==”写成“=”了
…
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: