zoukankan      html  css  js  c++  java
  • 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 代码
     
  • 相关阅读:
    C# winform 打包成安装程序(exe)
    gitHub----【Mac】sourcetree连接github,报错:fatal:Authentication failed for'https://git…。或提示password required 解决方案
    python3-----往一个字符串中循环添加数据
    python3.8----从多层嵌套Json中解析所需要的值
    记录一些工作知识
    【转】彻底搞懂 async & defer
    【转】判断JS数据类型的四种方法
    动态表单设计
    封装,继承,多态
    语义化版本
  • 原文地址:https://www.cnblogs.com/benpaobadaniu/p/4805223.html
Copyright © 2011-2022 走看看