Foundation框架
OC中的所谓框架,其实就相当于Java中的包,就是众多API的集合。具体来说,框架就是由类、方法、函数、文档按照一定的逻辑组织起来的集合,以使开发程序变得更便利。在OS X下的Mac系统中大约有80个框架,其中最基础的称为Foundation 框架。我们可以把Foundation 框架理解为其他编程语言中的标准库。
Foundation框架中大约有125个可用的头文件,使用#import语句导入。注意,Foundation框架中的类都是以NS为前缀的。
数值对象
在OC中,NSNumber类用来将基本数据类型的数字转为对象类型。在一些数据结构容器中保存的是对象而不是基本类型,因此需要将基本类型转换成对象类型才能保存。这相当于Java语言中基本数据类型的装箱类。
// 1. 字面量创建数值类型对象
NSNumber* num1 = @18;
int n = 20;
// 变量应使用括号
NSNumber* num2 = @(n);
// 2. 通过方法创建
NSNumber *intNum = [NSNumber numberWithInt:28];
NSNumber *floatNum = [NSNumber numberWithFloat:3.14f];
NSNumber *doubleNum = [NSNumber numberWithDouble:256.284];
NSNumber *boolNum = [NSNumber numberWithBool:1];
// 数值对象类型转基本类型
NSNumber* numberDouble = [NSNumber numberWithDouble: 3.1415926535];
double doubleNum = [numberDouble doubleValue];
int intNum = [numberDouble intValue];
// 数值对象类型转字符串类型
NSString *theString = [numberDouble stringValue];
字符串
在OC中,提供了两个操作字符串的类,分别是 NSString 类和 NSMutableString类,其中,使用 NSString类表示的字符串被称为不可变字符串,使用NSMutableString类表示的字符串被称为可变字符串。(类比Java或Dart中的String与StringBuilder)
// 1. 字面常量初始化一个NSString
NSString *str = @"Welcome to Objective-C";
// 2. 调用方法初始化
NSString *s1 = [NSString string];
NSString *s2= [[NSString alloc]initWithFormat:@"I'm %d years Old.", 18];
NSString *s3 = [NSString stringWithFormat:@"I'm %d years Old.", 18];
// 3. 从C语言字符串创建
NSString *s1 = [[NSString alloc] initWithUTF8String:"Objective-C"];
const char *cs = [s1 UTF8String]; // 将OC字符串转换回C字符串
将字符串转为基本数据类型
NSString *str1 = @"110";
// 转整形
int n = str1.intValue
NSString *str2 = @"10.1";
// 转浮点数
double d = str2.doubleValue
// 转布尔类型
NSString *bStr = @"true";
BOOL b = bStr.boolValue;
字符串的常见操作
NSString *str boo= @"bczl";
NSUInteger count = [str length]; // 获取字符串长度
NSLog(@"长度%lu",count);
for (int i = 0; i<count; i++) {
char c = [str characterAtIndex:i]; //获取当前位置字符串的字符
NSLog(@"第%d位=%c",i,c);
}
NSString *str1 = @"HELLO,WORLD";
NSLog(@"str1:%@",[str1 uppercaseString]); // 转为大写
NSLog(@"str1:%@",[str1 lowercaseString]); // 转为小写
NSLog(@"str1:%@",[str1 capitalizedString]); // 首字母大写
// 比较字符串
NSString *str2 = @"编程之路从0到1";
NSString *str3 = @"编程之路";
BOOL result= [str2 isEqualToString:str3];
NSLog(@"%d",result);
// 是否以另一个字符串开头
BOOL result2 = [str2 hasPrefix:@"编程"];
NSLog(@"%d",result2);
//判断一个字符串是否以另一个字符串结尾
BOOL result3 = [str2 hasSuffix:@"从0到1"];
NSLog(@"%d",result3);
NSString *str4 = @"WElCOME";
NSString *str5 = @"welcome";
NSComparisonResult result4 = [str4 compare:str5];
if(result4 != NSOrderedSame){
NSLog("相同");
}
NSComparisonResult result5 = [ @"WElCOME" caseInsensitiveCompare:@"welcome"];
if(result5 == NSOrderedSame){
NSLog("相同");
}
// 字符串拼接
NSString * string1 = [@"Hello," stringByAppendingString:@" OC"];
// 字符串分割
NSString *string2 =@"2021-04-30";
NSArray *array = [string2 componentsSeparatedByString:@"-"];
NSLog(@"array:%@",array);
字符串的查找
NSString *str1 = @"编程之路从0到1";
NSString *str2 = @"编程之路";
NSString *str3 = @"从0到1";
// 判断str2在str1中的位置
NSRange range1 = [str1 rangeOfString:str2];
NSUInteger location1 = range1.location; // 获取str2在str1中范围的位置
NSUInteger length1 = range1.length; // 获取str2的长度
// 打印输出str2的范围
if (location1 != NSNotFound) { // 如果Location1能找到
NSLog(@"%lu,长度为%lu",location1,length1);
}else NSLog(@"找不到");
// 判断str3在str1中的位置
NSRange range2 = [str1 rangeOfString:str3];
NSUInteger location2 = range2.location; //获取str3在str1中范围的位置
NSUInteger length2 = range2.length; //获取str3的长度
// 打印输出str3的范围
if (location2 != NSNotFound){
NSLog(@"%lu,长度为%lu",location2,length2);
} else NSLog(@"找不到");
// NSRange表示一个范围,通常是字符串里的字符范围或者数组里的元素范围
// NSRange有2个成员
// location : 表示该范围的起始位置
// length : 表示范围内的长度
// 创建
NSRange range = {7, 3};
NSRange range = NSMakeRange(7, 3);
字符串的截取
NSString *str1 = @"Objective-C is a good language";
// 从开头截取到指定位置,但不包括该位置的字符
NSString *str2 = [str1 substringToIndex:3];
NSLog(@"str2:%@",str2);
// 指定位置开始,一直到结束位置
NSString *str3 = [str1 substringFromIndex:3];
NSLog(@"str3:%@",str3);
// 按照给出的位置,长度,任意地从字符串中截取子串
NSString *str4 = [str1 substringWithRange:NSMakeRange(0, 4)];
NSLog(@"str4:%@",str4);
可变字符串
NSString类创建的字符串是不可变的,即一旦创建,字符串的内容和长度都是不可变的。如果需要对这个字符串进行修改,则只能创建新的字符串,这样的操作非常耗费内存。因此,OC提供了一个NSMutableString 类,它是NSString的子类,其创建的字符串长度和内容都是可变的。
NSMutableString * mStr = [NSMutableString string];
// 增加
[mStr appendString:@"Hello"];
// 格式化添加
[mStr appendFormat:@"有%d年的历史了", 20];
NSMutableString *str = [NSMutableString stringWithFormat:@"编程之路从0到1"];
//删除包含的子串
[str deleteCharactersInRange: [str rangeOfString:@"从0到1"]];
NSLog(@"str = %@",str);
// 修改
NSMutableString *str2 = [NSMutableString string];
str2.string = @"PHP是世界上最好的语言";
NSLog(@"%@", str2);
[str2 replaceCharactersInRange:[str2 rangeOfString:@"PHP"] withString:@"Java"];
//把PHP替换成Java
NSLog(@"%@", str2);
需要注意,如下以字母量声明的NSMutalbeString类对象,始终是NSString类型,而不是可变字符串类型。
NSMutalbeString *s1 = @"Bruce";
// 报错
[s1 insertString:@"My name is " atIndex:0];
数组
NSArray是OC中的数组类,OC编程中应尽量使用NSArray替代C语言中的数组。需要注意,NSArray只能存放OC对象,不能存储非OC对象,一旦初始化完毕后,内容就是固定的, 不能增删修改元素。
// 字面量创建
NSArray *array = @[@"Java",@"Dart",@"OC"];
// NSArray *array0 = [NSArray arrayWithOjects: @"Java",@"Dart",@"OC",nil];
// 创建一个空数组
NSArray *array1 = [NSArray array];
NSLog(@"%@",array);
NSLog(@"%@",array1);
// 获取数组长度
NSLog(@"%tu",array.count);
// 根据索引取值
NSLog(@"%@",array[0]);
NSLog(@"%@",[array objectAtIndex:0]);
// 取第一个和最后一个元素
NSLog(@"%@",array.firstObject);
NSLog(@"%@",array.lastObject);
// 是否包含指定元素
NSLog(@"%d",[array containsObject:@"Java"]);
// 数组连接成字符串
NSArray *arr = @[@"Aa", @"Bb", @"Cc", @"Dd"];
NSString *res = [arr componentsJoinedByString:@"-"];
NSLog(@"%@", res);
// 数组遍历
// 传统for循环遍历
for (int i = 0; i < array.count; i++) {
NSLog(@"%@",array[i]);
}
// 增强for循环遍历
for (NSString *str in array) {
NSLog(@"%@",str);
}
// Block 遍历
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *stop) {
NSLog(@"%@,index is %lu", obj, i);
}];
可变数组
在OC中,NSArray类创建的数组是不可变的,并且数组内的元素不能进行变化。而很多时候数组是需要动态改变的,这时,可以使用NSMutableArray类来实现。NSMutableArray是NSArray类的子类,它创建的数组是可变的。
// 创建空数组
NSMutableArray *arr = [NSMutableArray array];
// 创建空数组,并且指定容器长度为5
NSMutableArray *arr2 = [[NSMutableArray alloc] initWithCapacity:5];
// 创建一个包含两个元素的数组
NSMutableArray *arr3 = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
// 调用对象方法创建数组
NSMutableArray *arr4 = [[NSMutableArray alloc] initWithObjects:@"1",@"2", nil];
// 添加
[arr addObject:@"Alex"];
// 合并两个数组
[arr addObjectsFromArray:@[@"Bob", @"Bill",@"Charles"]];
NSLog(@"%@", arr);
// 插入
[arr insertObject:@"Alice" atIndex:1];
NSLog(@"%@", arrM);
// 删除
[arr removeObjectAtIndex:0];
[arr removeLastObject];
[arr removeObject:@"Bill"];
// 替换
arr[0] = @"ZS";
[arr replaceObjectAtIndex:1 withObject:@"Louis"];
特别需要注意,可变数组不能通过字面量方式创建,如下方式创建的只能是不可变数组。
NSMutableArray *arr = @[@"A", @"B"]; // 错误
字典
字典是用来存储键值对形式数据类型的集合(即其他编程语言中的Map)。和数组一样,OC 中的字典类也有不可变和可变类型,其中,不可变字典用 NSDictionary类表示,可变字典用NSMutableDictionary类表示。需要注意的是,字典是无序的。
// 字面量创建字典
NSDictionary *dict = @{@"name":@"张三", @"phone",@"911", @"address",@"北京东路"};
// 类方法创建字典
NSDictionary *dict2 = [NSDictionary dictionaryWithObjectsAndKeys:@"name":@"张三", @"phone":@"911", nil];
// 通过两个元素一一对应的数组创建字典
NSDictionary *dict3 = [NSDictionary dictionaryWithObjects:@[@"Bill", @"18"] forKeys:@[@"name", @"age"]];
// 根据Key值获取Value
NSLog(@"%@", dict[@"name"]);
NSLog(@"%@", [dict objectForKey:@"name"]);
// 字典的遍历
for (int i = 0; i < dict.count; ++i) {
// 获取字典中所有的key
NSArray *keys = [dict allKeys];
NSString *key = keys[i];
NSString *value = dict[key];
NSLog(@"key = %@, value = %@", key, value);
}
for (NSString *key in dict) {
NSString *value = dict[key];
NSLog(@"key = %@, value = %@", key, value);
}
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"key = %@, value = %@", key, obj);
}];
可变字典
NSMutableDictionary是NSDictionary的子类,它是可变的,随时可以往里面添删改查元素。
// 创建一个空字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSLog(@"%@", dict);
// 添加
[dict setObject:@"李四" forKey:@"name"];
// 合并两个字典
[dict setValuesForKeysWithDictionary:@{@"age":@"18", @"height":@"1.75"}];
NSLog(@"%@", dict);
// 获取
NSLog(@"name = %@", dict[@"name"]);
// 删除
[dict removeObjectForKey:@"name"];
[dict removeObjectsForKeys:@[@"age", @"height"]];
NSLog(@"%@", dict);
// 修改
// 给相同的key赋值, 那么新值会覆盖旧值
[dict setObject:@"8" forKey:@"age"];
dict[@"age"] = @"28";
同样的,可变字典NSMutableDictionary也不能使用字面量写法来创建。
文件
文本文件
// 写文件
NSString *str = @"编程之路从0到1";
BOOL flag = [str writeToFile:@"/Users/arcticfox/Desktop/test.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (flag == 1){
NSLog(@"写入成功");
}
// 读文件
NSError *error = nil;
NSString *content = [NSString stringWithContentsOfFile:@"/Users/arcticfox/Desktop/test.txt" encoding:NSUTF8StringEncoding error:&error];
if (error) {
NSLog(@"读取失败, 错误原因:%@", [error localizedDescription]);
} else {
NSLog(@"读取成功, 内容:\n%@", str);
}
归档和反归档
所谓对象归档是指将对象的状态以某种数据格式并以文件的方式持久地保存下来。需要时再将文件内容转换为对象。这两个过程叫做归档和反归档。这其实是苹果的叫法,实际上更常用的叫法是序列化和反序列化。
归档的数据文件格式可以是XML文件格式,也可以是key-value(键值对)格式。XML文件格式也叫属性列表,简称 plist。使用 key-value(键值对)方式存取需要使用NSKeyedArchiver 类来实现。自定义的类需要实现 NSCoding 协议,并实现协议方法才能进行归档。
plist 文件
plist 是Property List的缩写,它是一种属性列表文件,专门用来存储序列化后的对象,这些对象中的数据是实际是以 XML 格式存储。
// 写入 NSArray
NSArray *arr = @[@"lnj", @"lmj", @"jjj", @"xcq"];
BOOL flag = [arr writeToFile:@"/Users/arcticfox/Desktop/persons.plist" atomically:YES];
NSLog(@"%i", flag);
// 读取 NSArray
NSArray *newArr = [NSArray arrayWithContentsOfFile:@"/Users/arcticfox/Desktop/persons.xml"];
NSLog(@"%@", newArr);
// NSDictionary 写入
NSDictionary *dict = @{@"name":@"张三", @"phone":@"911", @"address":@"北京东路"};
BOOL flag = [dict writeToFile:@"/Users/arcticfox/Desktop/dict.plist" atomically:YES];
NSLog(@"flag = %i", flag);
// 读取 NSDictionary
NSDictionary *newDict = [NSDictionary dictionaryWithContentsOfFile:@"/Users/arcticfox/Desktop/dict.plist"];
NSLog(@"newDict = %@", newDict);
key-value 格式
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"Tom",@"1",@"Kite",@"2",nil];
// 归档
[NSKeyedArchiver archiveRootObject:dic toFile:@"/tmp/test.archive"];
// 反归档
NSDictionary *dic2 = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/tmp/test.archive"];
其他
格式化日期
/// 生成日期字符串
NSDate *now = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 指定格式
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *str = [formatter stringFromDate:now];
NSLog(@"%@", str);
/// 日期字符串转NSDate对象
NSString *str = @"2020-06-28 19:53:24";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *date = [formatter dateFromString:str];
NSLog(@"%@", date);
NSValue
NSValue是NSNumber的父类, NSNumber只能包装数值类型,NSValue可将结构体包装后添加到容器中。
typedef struct{
int age;
char *name;
}Person;
Person p = {18, "Bill"};
// valueWithBytes: 指向结构体的指针
// objCType: 包装的数据类型
NSValue *pValue = [NSValue valueWithBytes:&p objCType:@encode(Person)];
// 添加到数组中
NSArray *arr = @[pValue];
NSLog(@"%@", arr);
// 从NSValue中取出
Person per;
[pValue getValue:&per];
NSLog(@"age = %i, name = %s", per.age, per.name);
URL
即Uniform Resource Locator,统一资源定位符,是互联网上标准资源的地址。
// 通过完整的字符串创建
NSURL *url = [NSURL URLWithString:@"file:///Users/arcticfox/Desktop/test.txt"];
// 通过文件路径创建
NSURL *url = [NSURL fileURLWithPath:@"/Users/arcticfox/Desktop/test.txt"];
公众号“编程之路从0到1”