我在学习iphone开发教程的中第8章(也就是《iOS5开发基础教程》最新版的“08 - Sections2”下载地址:http://vdisk.weibo.com/s/hBHg6)
要为一个tableView实现搜索功能的时候,遇到了关于这个NSMutableDictionary一个问题,学习了好长时间终于想通,现在将问题以及我的理解总结一下.
《iOS5开发基础教程》
其中,在SectionViewController.m 中有这样一个方法:
-(void)resetSearch {
self.names = [self.allNames mutableDeepCopy];
NSMutableArray *keyArray = [[NSMutableArray alloc] init ];
[keyArray addObject:UITableViewIndexSearch];
[keyArray addObjectsFromArray:[[self.allNames allKeys] sortedArrayUsingSelector:@selector(compare:)]];
self.keys = keyArray;
}
其中书中这样提及:
我们需要刷新keys数组,因为如果某搜索排除了某分区中的所有值,那么还需要除去这一分区。否则,屏幕将被标题和空的分区充满,这看起来很糟糕、我们不希望为不存在的内容提供索引,因此根据搜索短语挑选名称时,还需要去除空的分区。
为什么不刷新keys数组就会出现“屏幕将被标题和空的分区充满”这种情况呢?
-(void)handleSearchForTerm :(NSString *)searchTerm {
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init ];
[self resetSearch];
for (NSString *key in self.keys) {
NSMutableArray *array = [namesOfSearched valueForKey:key];
NSMutableArray *toRemove = [[NSMutableArray alloc] init ];
for (NSString *name in array) {
if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound)
//NSCaseInsensitiveSearch:不区分大小写比较 NSLiteralSearch:进行完全比较,区分大小写 NSNumericSearch:比较字符串的字符个数,而不是字符值。
[toRemove addObject:name];
}
if ([array count]== [toRemove count])
[sectionsToRemove addObject:key];
[array removeObjectsInArray:toRemove];
}
[self.keys removeObjectsInArray:sectionsToRemove ];
[table reloadData];
}
其中有一句
[self.keys removeObjectsInArray:sectionsToRemove ];
这句将keys去除了一些成员,而字典的数量是不变的。为什么呢?
再来看一下resetSearch:其中的这一语句
self.namess = [self.staticDictionary mutableDeepCopy];
mutableDeepCopy的实现方法如下
- (NSMutableDictionary *)mutableDeepCopy {
NSMutableDictionary *returnDict = [NSMutableDictionary dictionaryWithCapacity:[self count]];
NSArray *keys = [self allKeys];
for (id key in keys) {
id oneValue = [self valueForKey:key];
id oneCopy = nil;
if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
oneCopy = [oneValue mutableDeepCopy];
else if ([oneValue respondsToSelector:@selector(mutableCopy)])
oneCopy = [oneValue mutableCopy];
if (oneCopy == nil)
oneCopy = [oneValue copy];
[returnDict setValue:oneCopy forKey:key];
}
return returnDict;
}
dictionaryWithCapacity:
所以字典数量不变,而数组数量改变之后就会出现所谓的“屏幕将被标题和空的分区充满”这种情况
下面详细介绍一下NSMutableDictionary
NSMutableDictionary 用于处理值对集合。保存到键的对象必须实现了copyWithZone:方法。和NSMutableArray一样添加到容器时对象收到retain消息,把对象从容器中移除时收到release消息,任何想在移除对象还要对该对象进行操作必须先对该对象发出一条retain消息,在使用完成后需要release。
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//创建Dictionary,Capacity仅控制初始化大小
NSMutableDictionary *fruits = [NSMutableDictionary dictionaryWithCapacity:2];
[fruits setObject:@"Orange" forKey:@"OrangeKey"];
[fruits setObject:@"Apple" forKey:@"AppleKey"];
[fruits setObject:@"Blueberry" forKey:@"BlueberryKey"];
NSLog(@"%@", fruits);
//获取一个对象
id oneObj = [fruits objectForKey:@"AppleKey"];
NSLog(@"%@", oneObj);
//如果找不到应的条目,返加nil
id noObj = [fruits objectForKey:@"aaa"];
NSLog(@"%@", noObj);
[pool drain];
return 0;
}