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(0, 10, 0, 10);
    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 == 0) {
        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] == 1) {
            [_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":@"13523526303",@"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 == 0) {
        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(50, 50)];
    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 40;
}
#pragma mark---cell行高
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 90;
}
#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
View Code 代码
 
原文地址:https://www.cnblogs.com/benpaobadaniu/p/4805223.html