我在学习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; }