该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!
第11章 Foundation框架中的系统服务
本章介绍提供系统服务的Foundation框架类;
为网络、文件管理、进程间通信、系统信息检索、文本处理、线程和并发机制提供多种操作系统服务;
11.1 网络服务
Foundation框架含有各种支持网络服务的API;
接下来介绍访问网络主机信息的API;
以及利用Bonjour网络协议发布和发现网络服务的方式;
11.1.1 NSHost类
NSHost类含有多个用于访问网络主机信息的方法;
网络主机信息:
指连入网络的计算机和设备的网络名称和地址;
一个NSHost对象代表一个独立的网络主机;
使用该对象中的方法可以查找网络中计算机和其他设备的网络名称和地址信息;
示例:
我们使用NSHost对象中的currentHost和name方法,获取运行该程序的主机的名称;
(Code)
NSHost *myHost = [NSHost currentHost];
NSLog(@"%@",[myHost name]);
使用NSHost对象中的hostWithName:方法和address方法,通过域名创建对象;
(Code)
NSHost * appress = [NSHost hostWithName:@"www.apress.com"];
NSLog(@"%@",[appress address]);
注意:这是Mac OS上使用的类;
我们新建了一个工程C11HostInfoProject用于尝试使用这些类;
11.1.2 Bonjour网络服务
Bonjour是一种协议;
使用它可以自动创建可用的IP网络,而无需进行配置或手动干预;
因此也被称为零配置网络;
Bonjour专门用于使设备(如计算机和打印机)自动连接网络;
他执行了各种函数,包括服务发现、地址分配和主机名解析;
NSNetService类和NSNetServiceBrowser类提供了管理Bonjour网络服务的功能;
NSNetService类:
可以代表由应用发布或用作客户端的网络服务;
服务可以是你编写的程序发布的本地服务,也可以是你编写的程序需要使用的远程服务;
NSNetServiceBrowser类:
用于寻找已经发布的网络服务;
这两个类都必须通过委托对象完成方法调用;
每个类中的方法都是以异步的方式被调用,而且在运行循环中被执行;
(本章稍后会介绍使用NSRunLoop类管理运行循环的方法)
11.2 应用服务
应用服务中含有很多通用API,使用它们可以获取和设置与应用进程有关的信息;
NSProcessInfo类:
用于获取当前运行程序(即进程)的信息;
使用类方法processInfo可以获取当前进程的NSProcessInfo对象;
NSProcessInfo对象含有获取进程信息(如命令行参数、环境变量、主机名和进程名称等)的实例方法;
(Code)
NSString * nameProcess = [[NSProcessInfo processInfo] processName];
NSLog(@"nameProcess = %@",nameProcess);
log:
2017-12-22 14:12:16.780759+0800 精通Objective-C[1829:7270160] nameProcess = 精通Objective-C
NSUserDefaults类:
提供了管理用户首选项(user preferences)的API;
这些信息用于配置应用程序,会永久存储在本地文件系统中;
提供了首选项的应用程序使用户能够自定义该应用程序的行为;
NSUserDefaults类既含有设置和获取首选项的方法,也含有管理首选项系统其它方面的方法;
设置和获取首选项的方法支持原始数据类型和属性列表中类型的对象(即NSData、NSString、NSNumber、NSDate、NSArray和NSDictionary对象);
首选项以键值对形式存储在用户的默认数据库中;
设置首选项、获取首选项:
(Code)
NSUserDefaults * userDef = [NSUserDefaults standardUserDefaults];
[userDef setObject:@"Flower" forKey:@"USER_DATA_NAME"];
NSLog(@"%@",[userDef objectForKey:@"USER_DATA_NAME"]);
log:
2017-12-22 14:32:53.091750+0800 精通Objective-C[2035:7288558] Flower
11.3 正则表达式和文本处理
NSRegularExpression类:
用于在字符串中处理正则表达式;
正则表达式是一种设置和识别文本的模式;
NSRegularExpression类含有创建和初始化NSRegularExpression对象的方法,以及执行各自正则表达式操作(寻找匹配项、匹配的数值等)的方法;
Foundation框架中的NSOrthography、NSSpellServer和NSTextCheckingResult类主要用于处理文本;
NSOrthography类:
可用于描述文本的语言学内容(文本含有的脚本、脚本的主导语言和可能出现的其他语言、文本整体的主导脚本和语言);
NSSpellServer类:
提供了一种机制,通过该机制可以使应用程序的拼写检查器为所有应用程序提供拼写服务;
该类含有了用于配置拼写服务器的方法、提供拼写服务的方法和管理拼写检查进程的方法;
NSTextCheckingResult类:
用于描述被文本检查操作找到的项目;
所有对象都代表在文本块分析过程中找到的请求文本;
下述代码示例使用了NSRegularExpression对象,获取并显示了它的数据;
(Code)
NSError * error;
NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:@"world" options:NSRegularExpressionCaseInsensitive error:&error];//创建正则表达式
NSString * greeting = @"Hello, world!";
NSTextCheckingResult * match = [regex firstMatchInString:greeting options:0 range:NSMakeRange(0, [greeting length])];//获取正则表达式的查询结果
NSRange range = [match range];
NSLog(@"Match begins at %ldth character in string",range.location);
log:
2017-12-22 16:03:01.259091+0800 精通Objective-C[2869:7362601] Match begins at 7th character in string
11.4 文件系统实用程序
文件I/O类中含有许多用于使用文件和目录的API;
使用这些类可以显示文件路径;
对文件和目录执行基本操作;
查询系统中的目录;
以及使用数据流对文件、内存和网络资源执行输入/输出(I/O)操作;
11.4.1 应用程序包
NSBundle类:
可以容纳程序中使用的代码和资源;
使用这些类可以定位程序资源、以动态方式加载和卸载可执行代码以及协助进行本地化;
NSBundle类含有很多方法:
使用这些方法可以创建和初始化包、获取包对象和包类、加载包中的代码、寻找包中的资源、获取包中的信息和管理本地化;
第7、9章介绍了可选包,以及如何使用NSBundle类动态加载包和通过包类创建对象,可参考部分内容;
11.4.2 文件管理
NSFileHandle类:
提供了底层文件 管理 实用程序;
一个NSFileHandle类实例就是一个文件描述符的面向对象封装器;
该类含有多个方法:
使用它们可以创建和初始化文件句柄、获取文件描述符、使用文件句柄执行文件I/O操作以及关闭文件;
NSFileHandle类还支持异步文件操作;
使用该类中的许多创建犯法还可以得到文件描述符的所有权,而且会在释放对象后自动关闭文件;
NSFileHandle类还含有多个通过输入文件描述符创建NSFileHandle对象的方法;
在这种情况,可以使用closeFile方法关闭描述符;
使用NSFileHandle类的API,从系统中临时文件的默认存储位置读取了一个名为C11Example.txt的文件;
(Code_使用NSFileHandle类读取文件)
NSString * tmpDir = NSTemporaryDirectory();
NSString * myFile = [NSString stringWithFormat:@"%@/%@",tmpDir,@"C11Example.txt"];
NSFileHandle * fileHandle = [NSFileHandle fileHandleForReadingAtPath:myFile];
if (fileHandle) {
NSData * fileData = [fileHandle readDataToEndOfFile];
NSLog(@"%lu bytes read from file %@",(unsigned long)[fileData length],myFile);
}
NSFileManager类:
提供了执行基础文件系统操作的通用方法,这些操作包括创建文件管理器、查找目录、查询目录内容、管理文件和目录项、创建指向文件的软/硬链接、查询文件访问操作、获取/设置文件的系统属性以及管理iCloud存储项;
(Code_使用NSFIleManager类查看当前目录内容)
NSFileManager * filemgr = [NSFileManager defaultManager];
NSString * currentPath = [filemgr currentDirectoryPath];
NSArray * contents = [filemgr contentsOfDirectoryAtPath:currentPath error:&error];
NSLog(@"Contents:%@",contents);
if (contents) {
//检查一个文件是不是可执行文件
NSString * file = [NSString stringWithFormat:@"%@/%@",currentPath,contents[0]];
if ([filemgr isExecutableFileAtPath:file]) {
NSLog(@"%@ is executable",file);
}
}
log:
2017-12-25 15:02:11.932055+0800 精通Objective-C[22782:8071899] Contents:(
".HFS+ Private Directory Data
",
home,
usr,
".Spotlight-V100",
net,
".DS_Store",
".PKInstallSandboxManager",
".PKInstallSandboxManager-SystemSoftware",
bin,
"installer.failurerequests",
Network,
sbin,
".file",
etc,
"User Information",
var,
Library,
".Trashes",
System,
".fseventsd",
private,
".DocumentRevisions-V100",
".vol",
Users,
Applications,
dev,
Volumes,
tmp,
cores
)
2017-12-25 15:02:43.526661+0800 精通Objective-C[22782:8071899] //.HFS+ Private Directory Data
is executable
11.4.3 数据流的输入输出
数据流:
是一种用于连续读取和写入数据的方便机制,无论数据是在内存中、文件中还是在网络上;
NSStream、NSInputStream和NSOutputStream类提供了从数据流读取数据和将数据写入数据流的功能;
NSStream是一个抽象类;
NSInputStream和NSOutputStream类是其具体子类;
数据流可以通过轮询操作,以异步的方式(通常为首选方式)或同步方式被读取和写入;
要通过异步方式访问数据流:
必须为数据流设置委托对象(及NSInputStream对象或NSOutputStream对象);
并将数据流安排到运行循环中;
该委托对象必须遵守NSStreamDelegate协议;
运行循环会调用该对象中的stream:handleEvent:方法处理数据流事件(状态、可用数据和错误条件);
示例:通过一个文件创建输入数据流,然后以同步方式从指定文件读取数据并将这些数据写入缓冲区;
(Code_NSInputStream类读取文件)
NSString * currentPath1 = [[NSFileManager defaultManager] currentDirectoryPath];
NSString * myFile1 = [NSString stringWithFormat:@"%@/%@",currentPath1,@"C11Example.txt"];
NSInputStream * ins = [NSInputStream inputStreamWithFileAtPath:myFile1];
[ins open];
if (ins && [ins hasBytesAvailable]) {
uint8_t buffer[1024];
NSUInteger len = [ins read:buffer maxLength:1024];
NSLog(@"Bytes read = %lu",len);
}
分析:
创建了输入数据流后,这段代码打开了该数据流;
使用NSInputStream类的hasBytesAvailable方法判断该数据流中是否含有可读取的字节;
有的话,则使用read方法将这些数据读取到缓冲区;
最后将读取的字节数记录到控制台;
11.4.4 元数据查询
NSMetadataItem系列类和NSMetadataQuery系列类:
提供了多个用于查询元数据的API,程序使用这些API可以根据文件或文件系统中的部分数据搜索文件;
像苹果的桌面搜索工具Spotlight一样,这些类一起提供了以编程方式使用文件元数据执行文件搜索的方法;
(只能在OS X上使用)
内容有些零散,主要是为了熟悉这些类的使用场景,我们继续。