Foundation框架之 NSString 和 集合

Posted __Sunshine_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Foundation框架之 NSString 和 集合相关的知识,希望对你有一定的参考价值。

本文主要介绍以下几部分

框架是由许多类、方法、函数、文档按照一定的逻辑组织起来的集合。
Foundation框架则定义Objective-C中底层的类,是Mac / ios 其他框架的基础。它不仅提供了一系列有用的基本对象类,还引入了一些在OC语言中没有的功能范式。Foundation框架的设计目的是:
(1)提供一套基本的实用类
(2)使得开发软件更容易
(3)支持Unicode字符串,对象持久化,对象分配
(4)提高OS独立性,增强可移植性

Foundation框架中大约有125个可用的头文件,但使用时只需要:

#import <Foundation/Foundation.h>

因为Foundation.h文件实际上导入了其他所有Foundation框架中的头文件。

如果不小心修改了系统自带的头文件,系统会报错,解决方法是:删除Xcode的缓存(缓存路径是)

下图是整理自:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/ObjC_classic/index.html

一、NSString

1、概念

一个NSString对象代表一个字符串(文字内容),也称NSString为字符串类。

2、创建:

(1)最直接的方式(这是常量字符串)

NSString *str1 = @"abc";
NSString *str2 = @"abc";
NSLog(@"str1 addr = %p", str1);     //= 0x100001038,存储在内存的常量区
NSLog(@"str2 addr = %p", str2);     //同上,可见字符串相同的常量的地址相同

(2)格式化的方式

NSString *str3 = [NSString stringWithFormat:@"%@", @"jack"];
NSString *str4 = [[NSString alloc] initWithFormat:@"the year is %d", 2015];
NSLog(@"str3 addr = %p", str3);     //= 0x6b63616a45 (?)
NSLog(@"str4 addr = %p", str4);     //= 0x100203e60,存储在内存的堆区

(3)从文件中读取

NSString *str0 = @"welcome";
NSError *err;
[str0 writeToFile:@"/Users/yons/Desktop/f.txt" atomically:YES encoding:NSUTF8StringEncoding error:&err];
//先把str0写入到文件去,写入成功则返回YES,err == nil;写入失败,则返回NO,err != nil
//error:后面的参数类型应该是 NSError **,是个二级指针,所以将指针 err 取地址

//判断是否写入成功
if (err != nil) 
    NSLog(@"write failed");
else
    NSLog(@"write successfully");


NSString *str5 = [NSString stringWithContentsOfFile:@"/Users/yons/Desktop/f2.txt" encoding:NSUTF8StringEncoding error:&err];
//从文件中读取字符串显示到控制台上

//判断是否读取成功
if (err == nil) 
    NSLog(@"read file successfully");
    NSLog(@"str5 = %@", str5);
else
    NSLog(@"read failed");

    //可以打印err的信息
    NSLog(@"%@", err);
    //也可以用:NSLog(@"%@", [err localizedDescription]); 来打印简单的错误信息
    

(4)从URL中读取

URL是Uniform Resource Locator(统一资源定位符)的简称。它是互联网上标准资源的地址,每一个URL对应唯一的资源,每个资源也对应唯一的URL。
URL的格式:应该包含协议、主机域名(服务器名称/IP地址)、路径。(即URL == 协议头://主机域名/路径)

3、比较大小

1)字符串依据排序顺序的不同,会有大小的差异。可以用对象方法 compare 来在两个NSString对象之间比较:

- (NSComparisonResult)compare:(NSString *)string;

如:

NSLog(@"%@ compare to %@: %ld", str1, str3, [str1 compare:str3]);
//比较两个字符串的内容大小。比较方法:逐个地将字符的ASCII值进行比较,比较结果为NSComparisonResult
//输出结果:abc compare to jack: -1

对 NSComparisonResult 的定义为:

typedef NS_ENUM(NSInteger, NSComparisonResult) NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending;

即:升序,结果为-1;降序,结果为1;相等,结果为0

也可以设置字符串比较的条件。如:

//加参数 NSNumericSearch 使得字符串会比较其中的数字
NSString *str1 = @"5a";
NSString *str3 = [NSString stringWithFormat:@"%@", @"12j"];
NSLog(@"%@ compare to %@: %ld", str1, str3, [str1 compare:str3]);
NSLog(@"%@ compare to %@: %ld", str1, str3, [str1 compare:str3 options:NSNumericSearch]);
//输出结果:
5a compare to 12j: 1    // 只是逐个字符时的结果
5a compare to 12j: -1   // 把字符中的连续数字当做整体来比较时的结果

options:后面的参数类型为 NSStringCompareOptions,定义为:

typedef NS_OPTIONS(NSUInteger, NSStringCompareOptions) 
    NSCaseInsensitiveSearch = 1,  //不区分大小写字符
    NSLiteralSearch = 2,          //完全比较,区分大小写(默认)
    NSBackwardsSearch = 4,         
    NSAnchoredSearch = 8,  
    NSNumericSearch = 64,         //比较字符串中的数字,如Foo2.txt < Foo7.txt < Foo25.txt
    NSDiacriticInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 128, 
    NSWidthInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 256, 
    NSForcedOrderingSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 512,
    NSRegularExpressionSearch NS_ENUM_AVAILABLE(10_7, 3_2) = 1024 
;

可以用“|”来添加多个限制条件。

2)判断是否相等
用对象方法 :

- (BOOL)isEqualToString:(NSString *)aString;

如:

NSString *str1 = @"abc";
NSString *str3 = [NSString stringWithFormat:@"%@", @"abc"];

NSLog(@"%@ equal %@? %d", str1, str3, [str1 isEqualToString:str3]);
//两个字符串的内容(不是地址)相比较,区分大小写,相同则返回YES,反正返回NO
NSLog(@"%@ == %@ ? %d", str1, str3, str1 == str3);
//"=="比较的是地址。

//输出结果:
abc equal abc? 1
abc == abc ? 0

4、前后缀检查及搜索

1)前缀检查
用对象方法:

- (BOOL)hasPrefix:(NSString *)aString;

如用于检查网址:

NSString *str8 = @"https://www.baidu.com";
NSString *str9 = @"https://";   //用于检查的前缀
//检查 str8 是否以 str9 为前缀
NSLog(@"\\"%@\\" has \\"%@\\" as prefix? %d", str8, str9, [str8 hasPrefix:str9]);
//运行结果:"https://www.baidu.com" has "https://" as prefix? 1

2)后缀检查
用对象方法 :

- (BOOL)hasSuffix:(NSString *)aString;

如用于检查网址:

NSString *str8 = @"https://www.baidu.com";
NSString *str10 = @".com";          //用于检查的后缀
//检查 str8 是否以 str10 为前缀
NSLog(@"\\"%@\\" has \\"%@\\" as suffix? %d", str8, str10, [str8 hasSuffix:str10]);
//运行结果:"https://www.baidu.com" has ".com" as suffix? 1

3)字符串查找
用对象方法:

- (NSRange)rangeOfString:(NSString *)aString;

用来检查字符串内容中是否包含了aString。如果包含,返回aString在字符串中第一次出现的范围
返回值类型 NSRange 是个结构体,用来表示范围,定义如下:

typedef struct _NSRange 
    NSUInteger location;   //范围的起始位置
    NSUInteger length;     //范围的长度
 NSRange;
// NSUInteger的定义
typedef long NSInteger;
typedef unsigned long NSUInteger;

如:

NSString *str8 = @"https://www.baidu.com";
NSRange range = [str8 rangeOfString:@"www"];
NSLog(@"range.loc:%ld, range.len:%ld", range.location, range.length);
//运行结果:range.loc:8, range.len:3

如果不包含,则返回的 NSRange 的 location 为 NSNotFound,length = 0
NSNotFound的定义如下:

enum NSNotFound = NSIntegerMax;
#define NSIntegerMax    LONG_MAX //即long型的最大值

如:

NSString *str8 = @"https://www.baidu.com";
NSRange range = [str8 rangeOfString:@"hehe"];
NSLog(@"range.loc:%ld, range.len:%ld", range.location, range.length);
//运行结果:range.loc:9223372036854775807, range.len:0

回想以前要查找数字或者字符串的时候用“==”或者“isEqualToString”,返回值为BOOL型,所以可以直接放在if()的括号中作判断,那现在在 NSString 找不到却返回 NSRange 型对象,而且它的 location 还是个很大值的 NSNotFound,则判断方法要作相应的变化:

NSString *str8 = @"https://www.baidu.com";
NSRange range = [str8 rangeOfString:@"hehe"];
if (range.location != NSNotFound)    //先进行判断
    NSLog(@"range.loc:%ld, range.len:%ld", range.location, range.length);
else
    NSLog(@"cannot find");

关于 NSRange 结构体的初始化,可以简单的直接赋值,也可以对逐个成员赋值、或者整体赋值,在OC中特有的创建+初始化方法是:

NS_INLINE NSRange NSMakeRange(NSUInteger loc, NSUInteger len) 
    NSRange r;
    r.location = loc;
    r.length = len;
    return r;

如:

NSRange range = NSMakeRange(7, 3);
//要查看 range 则用:
NSLog(@"%@", NSStringFromRange(range));
//运行结果:7, 3

4)字符串的截取和替换

i: 截取
用对象方法:

- (NSString *)substringFromIndex:(NSUInteger)from;
//从指定位置from(包含from)的字符开始,到尾部
- (NSString *)substringToIndex:(NSUInteger)to;
//从开头开始,截到指定位置to(不包含to)的位置
- (NSString *)substringWithRange:(NSRange)range;
//按照给出的范围range从字符串中截取子串
NSString *str8 = @"https://www.baidu.com";
NSLog(@"%@", [str8 substringFromIndex:5]); 
NSLog(@"%@", [str8 substringToIndex:5]);
NSLog(@"%@", [str8 substringWithRange:NSMakeRange(8, 4)]);
//运行结果:
://www.baidu.com
https
www.

ii: 替换
用对象方法:

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement NS_AVAILABLE(10_5, 2_0);
//在字符串中,用replacement去替换所有的target。
NSString *str8 = @"https://www.baidu.com";
NSLog(@"%@", [str8 stringByReplacingOccurrencesOfString:@"." withString:@"-"]);
//运行结果:https://www-baidu-com

5)NSString的其他用法
i: 获取字符串的每个字符

@property (readonly) NSUInteger length;
//字符串的length属性,表长度
- (unichar)characterAtIndex:(NSUInteger)index;
//返回index位置对应的字符

如:

NSString *str8 = @"https://www.baidu.com";
for (int i = 0; i < str8.length; i++) 
        //循环输出所有字符
   printf("%c ", [str8 characterAtIndex:i]);

printf("\\n");

ii: 字符串和其他数据类型的转换

NSString *s_1 = @"10";
NSLog(@"%d", [s_1 intValue]);       // NSString --> int
//输出结果:10

NSString *s_2 = @"3.14";
NSLog(@"%.2f", [s_2 floatValue]);   // NSString --> float
//输出结果:3.14

NSString *s_3 = @"1.111111111";
NSLog(@"%.8lf", [s_3 doubleValue]); // NSString --> double
//输出结果:1.11111111

NSString *s_4 = @"abc";
printf("%s\\n", [s_4 UTF8String]);   // NSString --> const char *,即C的字符串
//输出结果:abc

char aStr[] = "abcde";
NSLog(@"%@", [NSString stringWithUTF8String:aStr]);// const char * --> NSString
//输出结果:abcde

//去除字符或字符串:
NSString *str1 = @" aBcdhellocdBa ";
//去除首尾的空格
str1 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
//运行结果:aBcdhellocdBa         
//去掉开头和末尾所有的小写字母
str1 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet lowercaseLetterCharacterSet]];
//运行结果:BcdhellocdB        
//去掉开头和末尾所有的大写字母
str1 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet uppercaseLetterCharacterSet]];
//运行结果:cdhellocd        
//去掉开头和末尾所有的指定字符串 @"cd"
str1 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"cd"]];
//运行结果:hello

二、NSMutableString

NSString类 是不可变的(指字符串在内存中占用的存储空间固定,且存储的内容不能变化)。
NSMutableString类 继承自NSString类,是可变的(指字符串在内存中占用的存储空间可以不固定,且存储的内容能修改)。
NSString类的方法在NSMutableString类中都可以用。NSMutableString类可以看作一个字符串链表,可以动态地增删改查

        //创建一个空的可变长度的字符串
        NSMutableString *mstr = [NSMutableString string];
        NSLog(@"%@, len: %lu, addr: %p", mstr, mstr.length, mstr);
        //结果:, len: 0, addr: 0x100402a30

        //(1)增添:
        [mstr appendString:@"Jack"];
        //拼接“Jack”到最后面
        NSLog(@"%@, len: %lu, addr: %p", mstr, mstr.length, mstr);
        //结果:Jack, len: 4, addr: 0x100402a30

        [mstr appendFormat:@"%@",@" and Tom"];
        //拼接一段格式化的字符串到最后面
        NSLog(@"%@, len: %lu, addr: %p", mstr, mstr.length, mstr);
        //结果:Jack Tom, len: 12, addr: 0x100402a30

        // (2)删除
        //找到指定字符串的范围
        NSRange range_2 = [mstr rangeOfString:@"and"];
        //删除指定范围的字符串
        [mstr deleteCharactersInRange:range_2];
        //结果:Jack  Tom

        // (3)插入
        [mstr insertString:@"likes" atIndex:5];
        //结果:Jack likes Tom

        // (4)替换
        //找到要被替换的字符串的范围
        NSRange range_3 = [mstr rangeOfString:@"likes"];
        //将指定范围的字符串替换为"goes with"
        [mstr replaceCharactersInRange:range_3 withString:@"goes with"];
        //结果:Jack goes with Tom

注意:
(1)NSMutableString *mstr_2 = @”hello”; // 创建的是NSString类字符串,不是NSMutableString类字符串,不能修改


(2)一般使用NSString类字符串,只有在需要作特殊处理(增,删,插,替)时才用NSMutableString类字符串
(3)NSStringCompareOptions是位枚举,其值是2的0次方、1次方、2次方…

三、NSArray

Foundation框架用集合来管理多个对象,主要的形式有 NSArray(数组,有序的存储对象)、NSDictionary(字典,键值对)、NSSet(无序的存储对象)。示意图如下:

OC中的数组。
在C中,数组只能存储相同数据类型的元素,而且长度固定。
在C中,数组NSArray可以存储任意类型的OC对象(不能存储非OC对象,如基本数据类型),虽然NSArray和NSString一样是不可变的,但也有个子类NSMutableArray是可变的。

创建

//类方法
+ (instancetype)array;
+ (instancetype)arrayWithObject:(id)anObject;
+ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
//需要以 nil 作最后一个元素
+ (instancetype)arrayWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)arrayWithArray:(NSArray *)array;
//从xml文件中读取
+ (NSArray *)arrayWithContentsOfFile:(NSString *)path;
+ (NSArray *)arrayWithContentsOfURL:(NSURL *)url;
//对象方法(即用在 alloc 创建的一个新NSArray对象上)
- (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithArray:(NSArray *)array;
- (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;
- (NSArray *)initWithContentsOfFile:(NSString *)path;
- (NSArray *)initWithContentsOfURL:(NSURL *)url;
        NSArray *arr_1 = [NSArray array];           //不可变的空数组
        //数组不能存储nil,它是作为数组元素结束的标记。(类似'\\0'作为C中字符数组结束的标记)
        NSArray *arr_2 = [NSArray arrayWithObjects:@"10", @"3.14", @"mark", nil];//只有两个元素
        // 2012年之后可以快速创建数组(推荐使用):
        NSArray *arr_3 = @[@"5", @"7.8", @"John"]; //不需要用 nil 结尾
        NSLog(@"%@", arr_3);
        // 输出结果:(
        // 10,
        // mark
        // )

        //  数组的基本操作
        //获取集合元素个数
        NSUInteger cou = [arr_2 count];                 // cou = 2

        //获取指定位置的元素
        NSString *obj = [arr_2 objectAtIndex:2];        // obj = @"mark"
        // 2012年可以用下标快速访问数组(推荐使用):
        NSString *obj_2 = arr_2[2];                     // 效果同上

        //是否包含某一个元素
        BOOL isCont = [arr_2 containsObject:obj];       // YES

        //返回最后一个元素
        NSString *lastObj = [arr_2 lastObject];         // lastObj = @"mark"

        //返回第一个元素
        NSString *firstObj = [arr_2 firstObject];       // firstObj = @"10"

        //查找某元素在数组中的位置(找不到则返回NSNotFound)
        NSUInteger idx = [arr_2 indexOfObject:@"3.14"]; //idx = 1

        //在指定范围内查找指定元素在数组中的位置(若范围超出数组则报错)
        NSUInteger idx_2 = [arr_2 indexOfObject:@"mark" inRange:NSMakeRange(1, 2)];
        // idx_2 = 2

        // NSArray数组的遍历
        // (1) 下标遍历
        for (int i = 0; i < arr_2.count; i++) 
            NSLog(@"%@", arr_2[i]);
        

        // (2) for增强,快速遍历
        for (NSString *str in arr_2) 
            NSLog(@"%@", str);
        

        // (3) block遍历(最快)
        // 参数:obj 为遍历到的元素,idx 为下标, stop 默认为NO,当在block中设置为YES,则遍历退出
        [arr_2 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
            if (idx == 1) 
                *stop = YES;     // 只遍历到下标为1的元素
            
            NSLog(@"元素:%@ 的下标:%lu", obj, idx);
        ];
        //输出结果:
        //元素:10 的下标:0
        //元素:3.14 的下标:1

        // NSArray数组与文件
        // (1) 写入文件 (与NSString数据的写入类似)
        // 生成 .plist 文件
        if ([arr_2 writeToFile:@"/Users/yons/Desktop/arr.plist" atomically:YES]) 
            NSLog(@"NSArray write to .plist file successfully");
        


        // 生成 .xml 文件

        if ([arr_2 writeToFile:@"/Users/yons/Desktop/arr.xml" atomically:YES]) 



        // (2) 读取文件
        NSArray *arr_plist = [NSArray arrayWithContentsOfFile:@"/Users/yons/Desktop/arr.plist"];
        NSArray *arr_xml = [NSArray arrayWithContentsOfFile:@"/Users/yons/Desktop/arr.xml"];



        // NSArray数组与字符串
        // (1) NSArray --> 字符串
        // 用指定的字符串(如"#")逐个将数组的所有元素连接起来
        NSString *str_arr = [arr_2 componentsJoinedByString:@"#"];
        NSLog(@"%@", str_arr);
        //输出结果:10#3.14#mark

        // (2) 字符串 --> NSArray
        NSString *telStr = @"400-150-688";
        NSArray *arr_str = [telStr componentsSeparatedByString:@"-"];
        NSLog(@"%@", arr_str);
        // 输出结果:(
        // 400,
        // 150,
        // 688
        // )

四、NSMutableArray

NSArray类是不可变的。
NSMutableArray类是NSArray类的子类,是可变的,可以往数组里添加、更改、删除元素

1、创建和初始化
除了可以用NSArray的创建方法外,还可以用NSMutableArray特有的类方法和对象方法:

- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCapacity:(NSUInteger)numItems NS_DESIGNATED_INITIALIZER;//指定长度
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
+ (instancetype)arrayWithCapacity:(NSUInteger)numItems;
+ (NSMutableArray *)arrayWithContentsOfFile:(NSString *)path;
+ (NSMutableArray *)arrayWithContentsOfURL:(NSURL *)url;
- (NSMutableArray *)initWithContentsOfFile:(NSString *)path;
- (NSMutableArray *)initWithContentsOfURL:(NSURL *)url;

2、基本操作:

        //创建一个空数组
        NSMutableArray *marr = [NSMutableArray array];

        //添加一个元素
        [marr addObject:@"Sheldon"];
        [marr addObject:@"Leonard"];
        //marr = ( Sheldon,Leonard)

        //添加其他NSArray的全部元素到当前数组的最后面
        [marr addObjectsFromArray:arr_2];
        //marr = (Sheldon,Leonard,10,"3.14",mark)

        //在指定位置插入一个元素
        [marr insertObject:@"Penny" atIndex:2];
        //marr = (Sheldon,Leonard,Penny,10,"3.14",mark)

        //删除最后一个元素
        [marr removeLastObject];
        //marr = (Sheldon,Leonard,Penny,10,"3.14")

        //删除指定位置的元素
        [marr removeObjectAtIndex:4];
        //marr = (Sheldon,Leonard,Penny,10)

        //删除指定的元素
        [marr removeObject:@"10"];
        //marr = (Sheldon,Leonard,Penny)

        //删除指定范围内的所有元素
        [marr removeObjectsInRange:NSMakeRange(2, 1)];
        //marr = (Sheldon,Leonard)

        //用指定的对象替换指定位置的元素
        [marr replaceObjectAtIndex:1 withObject:@"Howard"];
        //也可以用下标快捷访问(推荐): marr[1] = @"Howard";
        //marr = (Sheldon,Howard)

        //交换两指定位置的元素
        [marr exchangeObjectAtIndex:0 withObjectAtIndex:1];
        //marr = (Howard,Sheldon)

        //删除所有元素
        //[marr removeAllObjects];
        //marr = ()
        NSLog(@"%@", marr);

注意:
类似 NSMutableString *mstr_2 = @”hello”;用NSMutableArray *marr_2 = @[@”2”];创建的只是NSArray类,不是NSMutableArray类,不能修改元素。

五、NSDictionary

翻译为“字典”,在生活中的“字典”可以通过一个拼音或汉字,就能检索到对应的详细解释。
NSDictionary类也有类似字典的作用:通过一个键(key),就能检索到对应的值(value)
NSDictionary类是不可变的,也有子类NSMutableDictionary类是可变的。
一个NSDictionary对象存储的是键-值对(键不能重复),而且数据是“无序的”,可以依据键来快速获取数据。

1、创建和初始化
NSDictionary类的创建方法都在NSDictionary类的类别NSDictionaryCreation中。如:

//创建空dictionary
+ (instancetype)dictionary;
//创建有一个指定的键-值对的dictionary
+ (instancetype)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
//创建有多个指定的键-值对的dictionary
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;

+ (instancetype)dictionaryWithDictionary:(NSDictionary *)dict;
+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
- (instancetype)initWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary;

2、基本操作

                   //创建。注意:key不可以重复,否则只是自动取前面的那个。
        NSDictionary *dict0 = [NSDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2", nil];
        //快速创建(推荐):
        NSDictionary *dict = @@"GD":@"GZ",@"HN":@"CS",@"HB":@"WH";
        NSLog(@"%@", dict);
        // dict = 
        //     GD = GZ;
        //     HB = WH;
        //     HN = CS;
        // 

        //返回字典的键值对数目
        NSLog(@"dict has %lu key-values", [dict count]);
        //输出结果:dict has 3 key-values

        //根据key取出value
        NSString *value_1 = [dict objectForKey:@"GD"];
        // value_1 = @"GZ"

        //快速获取元素(推荐):
        NSString *value_2 = dict[@"HB"];
        // value_2 = @"WH"

        // NSDictionary 的遍历
        // (1) for增强,快速遍历
        for (NSString *keyStr in dict) 
            //只是遍历所有的"key",没有遍历对应的"value",要调用对象方法objectForKey来遍历"value"
            NSLog(@"%@ = %@", keyStr, [dict objectForKey:keyStr]); //注意:输出是无序的
        

        // (2) block 遍历(最快)
        [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
            //key为键,obj为key对应的值,stop的值能控制暂停
            NSLog(@"key:%@, value:%@", key, obj);
        ];

        // NSDictionary 与文件
        // (1) 写入文件 (与NSString、NSArray的写入类似)
        // 生成 .plist 文件(也可以生产.xml文件)
        if ([dict writeToFile:@"/Users/yons/Desktop/dic.plist" atomically:YES]) 
            NSLog(@"NSDictionary write to .plist file successfully");
        

        // (2) 读取文件(也可以用URL读取)
        NSDictionary *dict_plist = [NSDictionary dictionaryWithContentsOfFile:@"/Users/yons/Desktop/dic.plist"];

        //既然 NSArray对象中的元素可以是任意OC对象,所以也可以是NSDictionary对象:
        NSDictionary *dict_2 = @@"JS":@"NJ", @"ZJ":@"HZ", @"SD":@"JN";
        //把两个NSDictionary对象放进一个数组:
        NSArray *arr_dic = @[dict,dict_2];
        //把NSArray对象写入文件
        if ([arr_dic writeToFile:@"/Users/yons/Desktop/arr_dic.plist" atomically:YES]) 
            NSLog(@"arr_dic write to .plist file successfully");
        


六、NSMutableDictionary

NSMutableDictionary是NSDictionary的子类,类似于NSMutableString是NSString的子类,NSMutableArray是NSArray的子类。
NSDictionary是不可变的,NSMutableDictionary可变的。

在NSMutableDictionary类的类别NSMutableDictionaryCreation中有几种创建和初始化的方法:

+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
+ (NSMutableDictionary *)dictionaryWithContentsOfFile:(NSString *)path;
+ (NSMutableDictionary *)dictionaryWithContentsOfURL:(NSURL *)url;
- (NSMutableDictionary *)initWithContentsOfFile:(NSString *)path;
- (NSMutableDictionary *)initWithContentsOfURL:(NSURL *)url;

还有一些操作如:

//依据aKey键删除对应的value
- (void)removeObjectForKey:(id)aKey;
//添加一个键值对(如果有重复,则只是最后一个有效)
- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
//删除所有的键值对
- (void)removeAllObjects;
//依据一组键值keyArray来删除它们对应的value
- (void)removeObjectsForKeys:(NSArray *)keyArray;
//将其他的字典添加到当前字典中去
- (void)setDictionary:(NSDictionary *)otherDictionary;

(对比下添加方法:NSMutableString用append,NSMutableArray用add,NSMutableDictionary用set)

对比:

问题:快捷访问只能取值,不能用于赋值?

七、NSSet

NSSet类是一种集合,无序地管理着对象


在NSSet类的类别NSSetCreation有以下一些创建方法:

//创建空set
+ (instancetype)set;
//创建含有一个对象的set
+ (instancetype)setWithObject:(id)object;
//创建含有多个对象的set,以nil为为结束标志
+ (instancetype)setWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
//用其他set来创建新的set
+ (instancetype)setWithSet:(NSSet *)set;
//用一个NSArray对象来创建新的set
+ (instancetype)setWithArray:(NSArray *)array;
//初始化方法:
- (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithSet:(NSSet *)set;
- (instancetype)initWithSet:(NSSet *)set copyItems:(BOOL)flag;
- (instancetype)initWithArray:(NSArray *)array;

在NSSet的类别NSExtendedSet有一些基本的操作:

//判断set中是否含有指定的对象
- (BOOL)containsObject:(id)anObject;
//判断两set是否相等(所有元素相同,判断方法用isEqual:)
- (BOOL)isEqualToSet:(NSSet *)otherSet;
//判断set是否是指定set的子集(判断用isEqual:)
- (BOOL)isSubsetOfSet:(NSSet *)otherSet;
//让set中所有元素都使用指定的无参方法
- (void)makeObjectsPerformSelector:(SEL)aSelector;
//让set中所有元素都使用指定的带参方法
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument;
//用block遍历set
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);

八、NSMutableSet

NSMutableSet是NSSet是子类

基本操作有:

//添加一个对象
- (void)addObject:(id)object;
//删除一个对象
- (void)removeObject:(id)object;
//初始化
- (instancetype)init NS_DESIGNATED_INITIALIZER;
//初始化并指定长度
- (instancetype)initWithCapacity:(NSUInteger)numItems NS_DESIGNATED_INITIALIZER;
//从指定的array中添加一些对象
- (void)addObjectsFromArray:(NSArray *)array;
//取交集
- (void)intersectSet:(NSSet *)otherSet;
//删除交集
- (void)minusSet:(NSSet *)otherSet;
//删除所有元素
- (void)removeAllObjects;
//合并两个set
- (void)unionSet:(NSSet *)otherSet;
//删除原set,再添加指定的otherSet的所有元素
- (void)setSet:(NSSet *)otherSet;
//用指定长度创建set
+ (instancetype)setWithCapacity:(NSUInteger)numItems;

以上是关于Foundation框架之 NSString 和 集合的主要内容,如果未能解决你的问题,请参考以下文章

Foundation框架中的不可变字符串:NSString

Foundation框架学习-NSString

Foundation框架系列-NSString

Foundation框架 之 常见结构体包装数据日期

Foundation框架 之 常见结构体包装数据日期

OC Foundation框架 字符串