UI:字典的两种取值的区别

字典的两种取值的区别 (objectForKey: 和 valueForKey )参考

一般来说 key 可以是任意字符串组合,如果 key 不是以 @ 符号开头,这时候 valueForKey: 等同于 objectForKey:,如果是以 @ 开头,去掉 key 里的 @ 然后用剩下部分作为 key 执行 [super valueForKey:]。

比如:

NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue"

forKey:@"theKey"];

NSString *value1 = [dict objectForKey:@"theKey"];

NSString *value2 = [dict valueForKey:@"theKey"];

这时候 value1 和 value2 是一样的结果。如果是这样一个 dict:

NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue"

forKey:@"@theKey"];// 注意这个 key 是以 @ 开头

NSString *value1 = [dict objectForKey:@"@theKey"];

NSString *value2 = [dict valueForKey:@"@theKey"];

value1 可以正确取值,但是 value2 取值会直接 crash 掉,报错信息:

Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[<__NSCFDictionary 0x892fd80> valueForUndefinedKey:]: this class is not key value coding-compliant for the key theKey.’

这是因为 valueForKey: 是 KVC(NSKeyValueCoding) 的方法,在 KVC 里可以通过 property 同名字符串来获取对应的值。比如:

@interface Person : NSObject

@property (nonatomic, retain) NSString *name;

@end

...

Person *person = [[Person alloc] init];

person.name = @"fannheyward";

NSLog(@"name:%@", [person name]);

//name:fannheyward

NSLog(@"name:%@", [person valueForKey:@"name"]);

//name:fannheyward

[person release];

valueForKey: 取值是找和指定 key 同名的 property accessor,没有的时候执行 valueForUndefinedKey:,而 valueForUndefinedKey: 的默认实现是抛出 NSUndefinedKeyException 异常。

回过头来看刚才 crash 的例子, [dict valueForKey:@"@theKey"]; 会把 key 里的 @ 去掉,也就变成了 [dict valueForKey:@"theKey"];,而 dict 不存在 theKey 这样的 property,转而执行 [dict valueForUndefinedKey:@"theKey"];,抛出 NSUndefinedKeyException 异常后 crash 掉。

objectForKey: 和 valueForKey: 在多数情况下都是一样的结果返回,但是如果 key 是以 @ 开头,valueForKey: 就成了一个大坑,建议在 NSDictionary 下只用 objectForKey: 来取值。

修改导航栏的背景颜色:参考

修改tableView 的右侧的索引的颜色:参考

更改索引的背景颜色:

self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];

更改索引的文字颜色:

self.tableView.sectionIndexColor = [UIColor blueColor];

tableview 的系统自带的编辑按钮的修改 参考

//
// RootViewController.m
// 13
//
// Created by lanounjw on 15/9/13.
// Copyright (c) 2015年 lanouhn. All rights reserved.
// #import "RootViewController.h"
#import "Contacts.h"
#import "ContactCell.h"
#import "UIImage+Scale.h"
#import "macroHeader.h" @interface RootViewController ()<UITableViewDataSource,UITableViewDelegate> @property(nonatomic,retain)NSMutableDictionary * dataDic;
@property(nonatomic,retain)NSMutableArray * sortedKey;
@property(nonatomic,retain)Contacts * per; @end @implementation RootViewController - (void)viewDidLoad {
[super viewDidLoad];
[self customerNavBar];
[self readFromLoca];
//创建 tableView
UITableView * tableview = [[UITableView alloc]initWithFrame:[[UIScreen mainScreen]bounds] style:UITableViewStylePlain];
tableview.separatorColor = [UIColor grayColor];
tableview.separatorInset = UIEdgeInsetsMake(, , , );
tableview.dataSource = self;
tableview.delegate = self;
//更改索引的背景颜色:
tableview.sectionIndexBackgroundColor = [UIColor clearColor];
//更改索引的文字颜色:
tableview.sectionIndexColor = UIColorFromHex(0x66CDAA);
self.view = tableview;
[tableview release]; } -(void)customerNavBar{
self.navigationItem.title = @"zzs150739";
UIBarButtonItem * left = [[UIBarButtonItem alloc]initWithImage:[[UIImage imageNamed:@"add_contact@2x"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(handleNewContact:)];
self.navigationItem.leftBarButtonItem = left;
[left release];
self.navigationController.navigationBar.barTintColor = UIColorFromHex(0x66CDAA);
#pragma mark---添加自带的编辑按钮
self.editButtonItem.title = @"编辑";
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.editButtonItem.tintColor = [UIColor whiteColor];
} #pragma mark---添加自带的编辑按钮后重写编辑的方法
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
[(UITableView *)self.view setEditing:editing animated:YES];
if (self.editing) {
self.editButtonItem.title = @"完成";
}else{
self.editButtonItem.title = @"修改";
}
} #pragma mark---设置某些区域可以被修改
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == ) {
return YES;//NO 就是不能被修改
}
return YES;
} #pragma mark---提交编辑状态
//处理数据以及页面(真正的数据是放在字典或者集合里)
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
NSString * key = [self.sortedKey objectAtIndex:indexPath.section];
NSMutableArray * group = [_dataDic objectForKey:key];
Contacts * contact = [group objectAtIndex:indexPath.row];
if (editingStyle == UITableViewCellEditingStyleDelete) {
if ([group count] == ) {
[_dataDic removeObjectForKey:key];
[_sortedKey removeObject:key];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationBottom];
}else{
[group removeObject:contact];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}else{
NSDictionary * dic = @{@"name":@"白白",@"gender":@"男",@"phoneNum":@"",@"photo":@"oooo"};
Contacts * newPer = [[Contacts alloc]initWithDic:dic];
[group insertObject:newPer atIndex:indexPath.row];
[tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
[newPer release];
}
} #pragma mark---tableView 的 cell 的移动
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
} #pragma mark---提交移动后的结果
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
NSString * key = [self.sortedKey objectAtIndex:sourceIndexPath.section];
NSMutableArray * group = [self.dataDic objectForKey:key];
Contacts * per = [[group objectAtIndex:sourceIndexPath.row]retain];
[group removeObjectAtIndex:sourceIndexPath.row];
[group insertObject:per atIndex:destinationIndexPath.row];
[per release];
} #pragma mark---限定 cell 的移动界限,禁止跨区运动
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath{
if (sourceIndexPath.section == proposedDestinationIndexPath.section) {
return proposedDestinationIndexPath;
}else{
return sourceIndexPath;
}
} #pragma mark---修改删除按钮的文字
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
return @"删除";
} #pragma mark---tableview的 cell 的编辑样式
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == ) {
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
} #pragma mark---
#pragma mark---添加联系人页面
-(void)handleNewContact:(UIBarButtonItem *)sender{
//添加联系人
} #pragma mark---读取本地数据
-(void)readFromLoca{
NSString * filePath = [[NSBundle mainBundle]pathForResource:@"contacts" ofType:@"plist"];
self.dataDic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
NSDictionary * dic = [NSDictionary dictionaryWithDictionary:_dataDic];
NSArray * sorted = [[dic allKeys]sortedArrayUsingSelector:@selector(compare:)];
self.sortedKey = [NSMutableArray arrayWithArray:sorted];
for (NSString * key in self.sortedKey) {
NSMutableArray * contactArr = [NSMutableArray array];
NSArray * group = [NSArray arrayWithArray:[_dataDic objectForKey:key]];
for (NSDictionary * dic in group) {
Contacts * per = [[Contacts alloc]initWithDic:dic];
[contactArr addObject:per];
}
[self.dataDic setObject:contactArr forKey:key];
}
} #pragma mark ---2个必须实现的方法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [[self.dataDic objectForKey:self.sortedKey[section]] count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * identifier = @"cell";
ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[ContactCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier];
}
NSString * key = [self.sortedKey objectAtIndex:indexPath.section];
NSArray * group = [self.dataDic objectForKey:key];
Contacts * contact = [group objectAtIndex:indexPath.row];
self.per = contact;
cell.nameLabel.text = _per.name;
cell.photoView.image = [[UIImage imageNamed:_per.photo] setScaleTOSize:CGSizeMake(, )];
cell.contentLabel.text = _per.phoneNum;
return cell;
} #pragma mark---右侧索引
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
NSArray * arr = [[self.dataDic allKeys]sortedArrayUsingSelector:@selector(compare:)];
return arr;
}
#pragma mark---标题页面
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
NSString * titleName = self.sortedKey[section];
return titleName;
}
#pragma mark---页眉行高
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return ;
}
#pragma mark---cell行高
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return ;
}
#pragma mark---分区数目
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [[self.dataDic allKeys] count];
} #pragma mark---内存警告
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
if ([self isViewLoaded] && !self.view.window) {
self.view = nil;
}
} @end

代码

上一篇:按键精灵关于抖音引流这件事。


下一篇:Linux(CentOS7)yum安装/卸载MySql数据库(V5.7)详细操作图解&常见问题