• iOS7 CookBook精彩瞬间(二)NSSet、通过Subscript访问类成员等


    1.NSSet的用法

       ①NSSet是一种无序集合,基于hash实现,可以在线性时间复杂度内查找某个元素,如果要让元素有序,应当使用NSOrderedSet,要让集合可变,与NSArray类似,使用NSMutableSet和NSMutableOrderedSet即可。

       ②从Set中取出元素只能用anyObject随机取,NSSet被系统用于存放用户的触摸点。

       ③Set的另一个特点是集合内元素唯一,重复向集合内添加同一元素是无效的。如果要实现集合中有多个重复元素,应该使用NSCountedSet。

       ④NSCountedSet本身是可变的,其元素重复原理是对元素个数进行计数,而不是真正的重复,调用方法countForObject:可以得到某个元素的个数。


    2.在自定义的类内实现用下标访问成员变量

       我们知道字典可以通过key拿到数据,如果类实现了字典的两个方法,借助于KVC可以实现下标访问,下面用一个例子来说明。

       按照CookBook中的例子,一个Person类有firstName和lastName两个成员,我们借助于键值来访问,需要实现两个方法:

    - (id)objectForKeyedSubScript:(id<NSCopying>)paramKey;
    - (void)setObject:(id)paramObject forKeyedSubscript:(id<NSCopying>)paramKey;
       苹果官方也许并不推荐这种做法,因此默认是没有提示的,有个技巧是先让类继承NSDictionary,然后可以根据提示打出这两个方法,然后再替换为NSObject或者其他基类。

       这两个方法一定要写在头文件里,然后就可以像字典那样访问成员变量了,如果不写在头文件,编译器会报错。

       下面是完整的代码:

       1.头文件

    #import <Foundation/Foundation.h>
    
    extern NSString *const kFirstNameKey;
    extern NSString *const kLastNameKey;
    
    @interface Person : NSObject
    
    @property (nonatomic, copy) NSString *firstName;
    @property (nonatomic, copy) NSString *lastName;
    
    - (id)objectForKeyedSubScript:(id<NSCopying>)paramKey;
    - (void)setObject:(id)paramObject forKeyedSubscript:(id<NSCopying>)paramKey;
    
    @end
        2.m文件,注意对键值的安全处理

    #import "Person.h"
    
    NSString *const kFirstNameKey = @"firstName";
    NSString *const kLastNameKey = @"lastName";
    
    @implementation Person
    
    - (id)objectForKeyedSubScript:(id<NSCopying>)paramKey{
        
        NSObject<NSCopying> *keyAsObject = (NSObject<NSCopying> *)paramKey;
        if ([keyAsObject isKindOfClass:[NSString class]]) {
            NSString *keyStr = (NSString *)paramKey;
            if ([keyStr isEqualToString:kFirstNameKey] || [keyStr isEqualToString:kLastNameKey]) {
                return [self valueForKey:keyStr];
            }
        }
        
        return nil;
        
    }
    
    - (void)setObject:(id)paramObject forKeyedSubscript:(id<NSCopying>)paramKey{
        
        NSObject<NSCopying> *keyAsObject = (NSObject<NSCopying> *)paramKey;
        if ([keyAsObject isKindOfClass:[NSString class]]) {
            NSString *keyStr = (NSString *)paramKey;
            if ([keyStr isEqualToString:kFirstNameKey] || [keyStr isEqualToString:kLastNameKey]) {
                [self setValue:paramObject forKey:keyStr];
            }
        }
        
    }
    
    - (NSString *)description{
        
        return [NSString stringWithFormat:@"%@ %@",_firstName,_lastName];
        
    }
    
    @end
        接下来我们就可以直接通过key访问成员变量了,之所以重写了description方法,就是为了打印出成员,来验证key可以设定值。

        验证代码如下:

    Person *p = [Person new];
    p[kFirstNameKey] = @"Tim";
    p[kLastNameKey] = @"Cook";
    NSLog(@"%@",p);
        打印如下:

    2015-08-31 18:19:44.742 iOS CookBookLearn[2825:36849] Tim Cook
        可以验证我们实现了通过key来访问成员变量。


    3.alertView判断按钮的清晰写法

       因为alertView在代理方法被调用时传入的是alertView本身和buttonIndex,一个常用的判断是直接判断buttonIndex等于几,这样对于大项目来说会提高交流成本,使得程序的可读性下降,一个比较好的办法是通过alertView的buttonTitleAtIndex:方法拿到标题,然后通过标题判断。


    4.对于默认宽高的控件,设置frame时width和height直接写0即可。


    5.DatePicker的成员属性minimumDate和maximumDate可以设置日期拾取区间限制。


    6.在iOS7和以后,UISlider的track images的宽度被限制为1,因此使用track image来自定义UISlider意义不大,应该使用minimumTrackTintColor和maximumTrackTintColor来设置轨道颜色。Slider的thumb宽高均为23,这也决定了Slider的默认高度为23不能改变。


    7.通过XIB加载视图,使用initWithNibName:bundle:方法,默认的bundle直接填nil即可。


  • 相关阅读:
    Swift入门篇-Hello World
    Swift入门篇-swift简介
    Minecraft 插件 world edit 的cs 命令
    搭建本地MAVEN NEXUS 服务
    MC java 远程调试 plugin 开发
    企业内部从零开始安装docker hadoop 提纲
    javascript 命令方式 测试例子
    ca des key crt scr
    JSF 抽象和实现例子 (函数和属性)
    form 上传 html 代码
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154034.html
Copyright © 2020-2023  润新知