Foundation框架是NS(NextStep)自建框架之一,提供了大量实现基本功能的类。
#import <Foundation/Foundation.h>
创建方法
NSString* str = [NSString new]; //[[NSString alloc] init];
NSString* str = [NSString string]; //返回一个空字符串
NSString* str = [NSString stringWithFormat:(nonnull NSString*), ...];//字符串拼接方法,最常用
NSString* str = [NSString stringWithUTF8String:char*]; //将C语言字符串转为OC字符串
char* cstr = str.UTF8String; //OC字符串转为C语言字符串
//上面的方法创建的字符串存储在堆中,下面则存储在数据段常量区
NSString* str = @"My String";//用@符号标识,否则是C字符串
建议使用
NSString* str = [NSString stringWithFormat:(nonnull NSString*), ...];
与
NSString* str = @"My String";
创建字符串。
常用方法
//返回字符串长度
NSUInteger len = [str length];//等价于str.length
//返回指定下标的字符
unichar ch = [str characterAtIndex:(int)];//unichar为两字节的字符类型,可以表示中文字符。本质是unsigned short。格式化输出用%C。
//比较两个字符串,类似strcmp
NSConparisonResult res = [str compare:(NSString*) options:(NS_OPTIONS)];//NSConparisonResult是-1,0,1的枚举类型,也可用int接收
//NS_OPTIONS包含一系列选项,如大小写敏感、数字比较规则等
//判断两个字符串相等
BOOL res = [str isEqualToString:(NSString*)];
//检查后缀
BOOL res = [str hasSuffix:@".txt"];
//NSRange
typedef struct _NSRange{
NSUInteger location;//子串下标
NSUInteger length; //长度
}NSRange;
//创建方式
NSRange range; range.location = 3; range.length = 4;
NSRange range = {3, 4};
NSRange range = {.location = 3, .length = 4};
NSRange range = NSMakeRange(3, 4);
//字符串切片
NSString* sub = [str substringFromIndex:(int)];//从参数位置截取到尾部
NSString* sub = [str substringWithRange:(NSRange)];
//搜索子串
NSRange res = [str rangeOfString:@"love" options:(NS_OPTIONS)];//NS_OPTIONS包含一系列选项,可决定搜索的方向
//将字符串转成数字类型
int value = str.intValue;
double value = str.doubleValue;
//以此类推。转换规则是从左到右开始转,直到无法转换的位置。
字符串的文件读写
/*写文件,返回值代表成功/失败,参数:
1 文件路径
2 是否启用临时文件缓冲,NO为不启用,效率高但不安全
3 编码。UTF-8编码为NSUTF8StringEncoding或者4
4 一个指针的地址,成功为nil,失败则存储错误信息。定义为NSError* err;用NSLog(@"%@", err);打印
*/
BOOL res = [str writeToFile:(NSString*) atomically:(BOOL) encoding:(NSStringEncoding) error:(NSError**)];
//读文件,参数:路径、编码、错误信息
str = [NSString stringWithContentFile:(NSString*) encoding:(NSStringEncoding) error:(NSError**)];
字符串的URL读写
既可以读写本地磁盘,也可以读写网页或者FTP上的文件
/*
URL写法
本地文件:file:///Users/.../file.txt
网页地址:http://www.baidu.com
FTP文件 :ftp://123.9.324.2/file.txt
*/
str = [NSString stringWithContentsOfURL:(NSString*) encoding:(NSStringEncoding) error:(NSError**)];
字符串的恒定性
内存中的NSString对象无法修改。当我们对这个对象进行修改,并不是在原来的对象上修改,而是创建了一个新的NSString对象,然后将指针指向新对象。
当创建一个NSString对象时,程序会先检查内存对应区域(堆区或者数据段)中是否已经存在相等的NSString字符串,存在则直接将指针指向这个字符串,否则再创建新字符串。
NSMutableString
是NSString的子类,该类创建的字符串可以更改,不会新创建一个对象。适合用于大批量字符串拼接。
//注意不能用NSString对象来初始化NSMutableString,否则就是子类指针指向父类对象
NSMutableString *str = [NSMutableString string];
NSMutableString *str = @"aasd";//这样可能会出问题
[str appendString:@"str1"]; //在字符串后追加字符串
结论:NSString类型作为属性时,@property的参数要用copy,而不是strong, weak, assign。
copy
是定义在NSObject类中的实例方法,作用是拷贝对象。
NSString类型调用copy是浅拷贝,直接返回对象本身的地址。会导致引用计数器+1。由于NSString不可变,指针修改指向时会创建一个新的NSString对象,所以浅拷贝即可。
NSMutableString类型调用copy是深拷贝,产生了一个NSString的新对象。
mutableCopy
NSString类型调用mutableCopy是深拷贝,产生了一个NSMutableString的新对象。
NSMutableString类型调用mutableCopy是深拷贝,产生了一个NSMutableString的新对象。
对于一般的类或自定义的类,可以手动实现copy方法来完成深拷贝。
定义在Foundation框架中,长度固定,内存连续。
元素类型是id类型,可以存储不同类型的对象,也只能存储OC对象,不能存储基本数据类型。其中,nil(即0)会被识别为数组的结尾。
注:往NSArray中传入数据时应先判断是否为nil,避免crash
创建之后数组长度不可变,所以创建空数组没有意义。
创建方法
NSArray *arr = @[obj1, obj2,...];//简要创建方法,用@标识数组,不需要nil。建议使用。
NSArray *arr = [NSArray arrayWithObjects:obj1, obj2,...,nil];//写完内容元素之后,要以nil结尾。不建议使用。
使用方法
arr[0]; //等价于[arr objectAtIndex:0];越界时会报错
arr.count; //获取长度
[arr containsObject:(NSObject*)]; //判断是否包含元素
[arr firstObject]; //获取首元素,如果arr为空则返回nil
[arr lastObject]; //获取尾元素,如果arr为空则返回nil
[arr indexOfObject:(NSObject*)]; //查找对象第一次出现的下标,没找到返回NSNotFound
遍历方法
for(int i=0; i<arr.count; i++){}
for(id i in arr){}
//使用代码块来遍历,包含对象、下标、停止标志(当要停止循环时将其置为YES)
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL* _Nonnull stop){}];
其他方法
NSString* str = [arr componentsJoinedByString:@"."]; //用连接符将数组中的元素连接成字符串
NSArray* arr = [str componentsSeparatedByString:"."];//用分隔符将字符串分成字符串数组
动态数组NSMutableArray
是NSArray的子类,该类创建的数组的元素可以动态增加和删除,即动态数组。
对可变数组的使用insert方法时应当特别注意下标越界和nil问题。
//创建方法
NSMutableArray* arr = [NSMutableArray new];//由于数组长度可变,所以可以创建空数组。
NSMutableArray *arr = @[obj1, obj2,...];//不可以用这个方法初始化,会导致子类指针指向父类对象
//新增元素
[arr addObject:obj];//增加元素到尾部
[arr addObjectFromArray:arr]; //从数组增加元素到尾部
[arr insertObject:obj atIndex:1];//在指定位置插入元素,注意越界问题
//删除元素
[arr removeObjectAtOndex:1];//删除指定位置元素
[arr removeObject:obj]; //删除特定元素
[arr removeObject:obj inRange:(NSRange)];//删除特定范围内的特定元素
[arr removeLastObject:obj]; //删除最后一个元素
[arr removeAllObject:obj]; //清空数组
定义在Foundation框架中,用来包装C数据类型。
StructTest s; //假设有这样一个结构体
NSValue* v = [NSValue valueWithBytes:s objCType:@encode(StructTest)];//包装过程
//对于一些内建的结构体如CGPoint、CGRect等,OC提供了更直接的方法,这里略
基本数据类型包装NSNumber
定义在Foundation框架中,用来包装基本数据类型,是NSValue的子类。
int a = 10;
NSNumber num = [NSNumber numberWithInt:a];
NSNumber num = [NSNumber numberWithDouble:10.1];
NSNumber num = @(a);//简化初始化方法,建议使用
NSNumber num = @10.1;//简化初始化方法,建议使用
int value = num.intValue;
int value = num.doubleValue;
NSArray *arr = @[num, @20];
定义在Foundation框架中,以键值对存储数据。
不可变,创建后无法增加和删除元素,所以创建空字典没有意义。
用键来标识数据,键不可重复,如果重复,后添加值的无效。
键只能是遵守NSCoping协议的OC对象,一般使用NSString;值只能是OC对象。
注:往NSDictionary中传入数据时应先判断是否为nil,避免crash
创建方法
//简要创建方法,建议使用
NSDictionary* dict = @{Key1:Value1, Key2:Value2,...};
//以值键值键顺序存放数据,需要nil结尾,不建议使用
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:...,nil];
使用方法
//无法使用下标访问
dict[@"key"];//[dict objectForKey:@"key"];不存在则返回nil
dict.count;//获取键值对数量
遍历方法
for (NSString* key in dict) {}
//使用代码块来遍历,与NSArray类似
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, id _Nonnull obj, BOOL* _Nonnull stop) {}];
持久化
[dict writeToFile:(NSString*) automically:(BOOL)];//将字典存入文件
NSDictionary* dict = [dict dictionaryWithContentsOfFile:(NSString*)];//从文件读取字典
可变字典NSMutableDictionary
是NSDictionary的子类,该类创建的字典可以动态增加和删除。
//创建方法
NSMutableDictionary* arr = [NSMutableDictionary new];//由于长度可变,所以可以创建空字典
//不允许这样初始化:
//NSMutableDictionary* dict = {Key1:Value1, Key2:Value2,...};
//增加和删除
[dict setObject:@"value" ForKey:@"key"];//添加时键有重复会覆盖旧的
[dict removeAllObjects];//清空
[dict removeObjectsForKey:@"key"];//删除指定键值对
通知的本体,主要作用是传递信息和数据。
@property(readonly, copy) NSNotificationName name; //通知名,用于标识通知,事实上是NSString *的别名
@property(nullable, readonly, retain) id object; //通知的发送者,用于筛选通知
@property(nullable, readonly, copy) NSDictionary *userInfo; //通知附带的信息,重要!
NSNotificationCenter 是单例模式,用于应用内不同对象之间的消息传递。
@property(class, readonly, strong) NSNotificationCenter *defaultCenter;
//发送通知
- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSNotificationName)aName
object:(id)anObject;
- (void)postNotificationName:(NSNotificationName)aName
object:(id)anObject
userInfo:(NSDictionary *)aUserInfo;//通知附带的信息
//添加通知的监听者
- (void)addObserver:(id)observer //通知接收者,一般是self
selector:(SEL)aSelector //收到通知后的行为,附带一个NSNotification *参数,用于接收通知附带的信息
name:(NSNotificationName)aName //通知名称,设置为nil表示不按名称筛选
object:(id)anObject; //通知发送者,设置为nil表示所有发送者
//移除监听者,一般在监听者dealloc时调用
- (void)removeObserver:(id)observer
name:(NSNotificationName)aName
object:(id)anObject;
- (void)removeObserver:(id)observer;
评论区