目录
字符串(NSString与NSMutableString)
创建字符串
NSString代表字符序列不可变的字符串,NSString的功能主要包括如下:
下面用代码为大家演示创建NSString对象的几种方式:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
UniChar data[6] = {65, 98, 66, 100, 101, 102};
//使用Unicode数值初始化字符串
NSString* str1 = [[NSString alloc]initWithCharacters:data length:6];
NSLog(@"%@", str1);
char* cstr = "hi,karry Wang!";
//将C风格的字符串转换为NSString对象
NSString* str2 = [NSString stringWithUTF8String:cstr];
NSLog(@"%@", str2);
//将字符串写入指定文件
[str2 writeToFile:@"myFile.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
//读取文件内容,用文件内容初始化字符串
NSString* str3 = [NSString stringWithContentsOfFile:@"myFile.txt" encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", str3);
//读取文件内容,用文件内容初始化字符串
NSString* str4 = [NSString stringWithContentsOfFile:@"NSString.m" encoding:NSUTF8StringEncoding error:nil];
//因为只能读取文本文件,所以这里的输出应该是null
NSLog(@"%@", str4);
}
return 0;
}
运行结果:
程序将str2字符串的内容写入了底层的myFile.txt文件,因此,运行此程序就会发现该文件的运行目录下多了一个myFile.txt文件,该文件内容就是str2的字符串。
tips:OC的文件操作与C语言类似,在写入文件时,如果文件不存在,它会自己创建一个的新的文件。
NSString的常用功能
得到NSString字符串之后,就可以调用NSString大量的功能性方法,其中的方法较多,此处只用代码示例常用方法的用法。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString* str = @"wonderful!";
NSString* comic = @"《间谍过家家》";
//在str后面追加笃定的字符串
//原来的字符串对象并不改变,只是将新生成的字符串重新赋给str指针变量
str = [str stringByAppendingString:@"spyFamily"];
NSLog(@"%@", str);
//获取字符串对应的C风格字符串
const char* str1 = [str UTF8String];
NSLog(@"获取的C字符串:%s", str1);
//在str后面追加带变量的字符串
//原来的字符串对象并不改变,只是将新生成的字符串重新赋给str指针变量
str = [str stringByAppendingFormat:@"%@是一部灰常好看的合家欢治愈搞笑番。", comic];
NSLog(@"%@", str);
NSLog(@"str的字符个数为:%lu", [str length]);
NSLog(@"str按UTF-8字符集解码后字节数为:%lu", [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
//获取str的前10个字符组成的字符串
NSString* s1 = [str substringToIndex:10];
NSLog(@"%@", s1);
//获取str从第10个字符之后开始,与后面字符组成的字符串
NSString* s2 = [str substringFromIndex:10];
NSLog(@"%@", s2);
//获取str从第10个字符之后开始,到以第10个字符为开始的第16个字符组成的字符串
NSString* s3 = [str substringWithRange:NSMakeRange(10, 16)];
NSLog(@"%@", s3);
//获取《间谍过家家》在str中出现的位置
NSRange location = [str rangeOfString:@"《间谍过家家》"];
//NSRange是一个包含两个成员变量(无符号的location和length)的结构体
NSLog(@"《间谍过家家》在str中出现的开始位置:%ld,长度为:%ld", location.location, location.length);
//将str的所有字符转为大写
NSString* str4 = [str uppercaseString];
NSLog(@"%@", str4);
}
return 0;
}
运行结果:
可变字符串(NSMutableString)
NSString类是不可变的类,即一旦NSString对象被创建,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
而NSMutableString对象则代表一个字符串序列可变的字符串。
而且NSMutableString是NSString的子类,因此,上一节说的NSString的方法,NSMutableString都可以直接使用,NSMutableString对象也可以直接当成NSString对象使用。
当一个NSMutableString被创建后,我们就可以用其提供的方法来改变字符串所包含的字符序列。
对应的代码演示如下:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString* comic = @"《间谍过家家》";
//创建一个NSMutableString对象
NSMutableString* str = [NSMutableString stringWithString:@"wonderful!"];
NSLog(@"%@", str);
//追加固定字符串
//字符串所包含的字符序列本身发生了改变,因此无需重新赋值
[str appendString:@"哇酷哇酷!"];
NSLog(@"%@", str);
//追加带变量的字符串
//字符串所包含的字符序列本身发生了改变,因此无需重新赋值
[str appendFormat:@"%@是一部灰常好看的搞笑治愈番。", comic];
NSLog(@"%@", str);
//在指定位置插入字符串
//字符串所包含的字符序列本身发生了改变,因此无需重新赋值
[str insertString:@"spyFamily!" atIndex:10];
NSLog(@"%@", str);
//删除从位置19以后开始的13个字符(即到位置33之前的所有字符)
[str deleteCharactersInRange:NSMakeRange(19, 13)]; //不含19和33
NSLog(@"%@", str);
//将从位置19以后开始的14个字符(即到位置33(包含33)的所有字符)替换为“快点出第三季!!!”
[str replaceCharactersInRange:NSMakeRange(19, 14) withString:@"快点出第三季!!!"];
NSLog(@"%@", str);
}
return 0;
}
运行结果:
日期与时间
OC为处理日期、时间提供了NSDate、NSCalendar对象,还提供了日期格式器来处理日期与字符串之间的转换。
日期与时间(NSDate)
NSDate对象代表日期与时间,OC既提供了类方法来创建NSDate对象,也提供了大量init开头的方法来初始化NSDate对象。
下面对NSDate类的常见方法用途给出代码示例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
//获取当前日期、时间
NSDate* date1 = [NSDate date];
NSLog(@"%@", date1);
//获取从当前时间开始,一天之后的日期
NSDate* date2 = [[NSDate alloc]initWithTimeIntervalSinceNow:3600 * 24];
NSLog(@"%@", date2);
//获取从当前时间开始,三天之前的日期
NSDate* date3 = [[NSDate alloc]initWithTimeIntervalSinceNow:-3 * 3600 * 24];
NSLog(@"%@", date3);
//获取从1999年1月1日开始往后20年的时间
NSDate* date4 = [[NSDate alloc]initWithTimeIntervalSince1970:3600 * 24 * 365 * 20];
NSLog(@"%@", date4);
//获取系统当前的NSLocale(NSLocale代表一个语言,这里表示中文)
NSLocale* current = [NSLocale currentLocale];
//获取NSDate在当前NSLocale下对应的字符串
NSLog(@"%@", [date1 descriptionWithLocale: current]);
//获取两个日期之间较早的日期
NSDate* earlier = [date1 earlierDate: date2];
NSLog(@"%@", earlier);
//获取两个日期之间较晚的日期
NSDate* later = [date1 laterDate: date2];
NSLog(@"%@", later);
/*比较两个日期用:compare:方法会返回NSComparisonResult枚举值,
该枚举类型包含NSOrderAscending、NSOrderSame和NSOrderDescending三个值,
分别代表调用compare:方法的日期位于被比较日期之前、相同、之后*/
switch ([date1 compare: date3])
{
case NSOrderedAscending:
NSLog(@"date1在date3之前");
break;
case NSOrderedSame:
NSLog(@"date1和date3时间想相同");
break;
case NSOrderedDescending:
NSLog(@"date1在date3时间之后");
break;
}
//获取两个时间的时间差
NSLog(@"date1与date3之间的时间差是%g秒", [date1 timeIntervalSinceDate:date3]);
NSLog(@"date2与现在的时间的时间差是%g秒", [date2 timeIntervalSinceNow]);
}
return 0;
}
运行结果:
由上面的代码,我们可以看出来,创建NSDate的类方法和实例方法基本相似,只是类方法以date开头,实例方法以init开头。在得到 NSDate 对象后,两个 NSDate 之间就可以比较大小,可以计算两个 NSDate 之间的时间差,也可以把 NSDate 转换为符合当前NSLocale 的格式字符串。
tips:NSLocale代表一个语言、国际环境。同样一个日期,在不同语言、国家环境下,显示出来的字符串是不同的。
日期格式器
NSDateFormatter代表一个日期格式器,它的作用是完成NSDate和NSString之间的转换。使用NSDateFormatter完成NSDate和NSString之间的转换的步骤如下:
- 创建一个NSDateFormatter对象。
- 调用NSDateFormatter的setDateStyle:、setTimeStyle:方法设置格式化日期、时间的风格。
其中日期、时间风格支持以下几个枚举值:
- NSDateFormatterNoStyle——不显示日期、时间的风格
- NSDateFormatterShortStyle——显示“短”的日期、时间的风格
- NSDateFormatterLongStyle ——显示“长”的日期、时间的风格
- NSDateFormatterMediumStyle——显示“中等”的日期、时间的风
- NSDateFormatterFullStyle——显示“完整”的日期、时间的风格
- 调用setDateFormate:方法设置自己想用的日期、时间的格式模版。
如果需要将 NSDate 转换为 NSString,则调用 NSDateFormatter 的stringFromDate:方法执行格式化即可;如果需要将 NSString 转换为 NSDate,则调用NSDateFormatter的dateFromString:方法执行格式化即可。
下面给出NSDateFormatter的功能和用法的代码示例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
//定义date并格式化为从1970年1月1日开始,20年之后的日期
NSDate* date = [NSDate dateWithTimeIntervalSince1970:3600 * 24 * 366 * 20];
//创建两个NSLocale,分别代表中国、美国
NSLocale* locales[] = {[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"], [[NSLocale alloc]initWithLocaleIdentifier:@"en_US"]};
//为上面两个NSLocale创建8个NSDateFormatter对象
NSDateFormatter* df[8];
for (int i = 0; i < 2; i++)
{
df[i * 4] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4]setDateStyle:NSDateFormatterShortStyle];
[df[i * 4]setTimeStyle:NSDateFormatterShortStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4]setLocale:locales[i]];
df[i * 4 + 1] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4 + 1]setDateStyle:NSDateFormatterMediumStyle];
[df[i * 4 + 1]setTimeStyle:NSDateFormatterMediumStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4 + 1]setLocale:locales[i]];
df[i * 4 + 2] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4 + 2]setDateStyle:NSDateFormatterLongStyle];
[df[i * 4 + 2]setTimeStyle:NSDateFormatterLongStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4 + 2]setLocale:locales[i]];
df[i * 4 + 3] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4 + 3]setDateStyle:NSDateFormatterFullStyle];
[df[i * 4 + 3]setTimeStyle:NSDateFormatterFullStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4 + 3]setLocale:locales[i]];
}
for (int i = 0; i < 2; i++)
{
switch (i) {
case 0: NSLog(@"-----中国日期格式------");
break;
case 1: NSLog(@"-----美国日期格式------");
break;
}
NSLog(@"SHORT格式的日期格式:%@", [df[i * 4]stringFromDate:date]);
NSLog(@"MEDIUM格式的日期格式:%@", [df[i * 4 + 1]stringFromDate:date]);
NSLog(@"LONG格式的日期格式:%@", [df[i * 4 + 2]stringFromDate:date]);
NSLog(@"FULL格式的日期格式:%@", [df[i * 4 + 3]stringFromDate:date]);
}
NSDateFormatter* df2 = [[NSDateFormatter alloc] init];
//设置自定义格式器模版
[df2 setDateFormat:@"公元yyyy年MM月DD日HH时mm分"];
//执行格式化
NSLog(@"%@", [df2 stringFromDate:date]);
NSString* dateStr = @"1999-09-21";
NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
//根据日期字符串的格式设置格式模版
[df3 setDateFormat:@"yyyy-MM-DD"];
//将字符串转化为NSDate对象
NSDate* date2 = [df3 dateFromString:dateStr];
NSLog(@"%@", date2);
}
return 0;
}
运行结果:
日历(NSCalendar)与日期组件(NSDateComponents)
为了能分开NSDate对象包含的各个字段数据,Foundation框架提供了NSCalendar对象,该对象包含了以下两个常用方法:
- (NSDateComponents*)components: fromDate:——从NSDate提取年、月、日、时、分、秒各时间字段的信息。
- dateFromComponents:(NSDateComponents*)comps:——使用comps对象包含的年、月、日、时、分、秒各时间字段的信息来创建NSDate。
上述两个方法中的NSDateComponents对象是专门用于封装年、月、日、时、分、秒各时间字段的信息,该对象只包含了对year、month、day、hour、minute、second、week、weekday等各字段的getter和setter方法。
下面给出用NSCalendar和NSDateComponents分开处理NSDate中个时间字段的数值的代码示例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
//获取代表公历的Calendar对象
NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
//获取当前日期
NSDate* date = [NSDate date];
//定义一个时间字段的旗标,指定将会获取指定年、月、日、时、分、秒的信息
unsigned unitFlags = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond|NSCalendarUnitWeekday;
//获取不同时间字段的信息
NSDateComponents* comp = [gregorian components:unitFlags fromDate:date];
//获取各时间字段的数值
NSLog(@"现在是%ld年", comp.year);
NSLog(@"现在是%ld月", comp.month);
NSLog(@"现在是%ld日", comp.day);
NSLog(@"现在是%ld时", comp.hour);
NSLog(@"现在是%ld分", comp.minute);
NSLog(@"现在是%ld秒", comp.second);
NSLog(@"现在是星期%ld", comp.weekday);
//上面输出的星期会比我们日历上的星期数多一,是因为西方把周天当作每周的第一天
//再次创建一个NSDateComponents对象
NSDateComponents* comp2 = [[NSDateComponents alloc]init];
//设置不同时间字段的数值
comp2.year = 2024;
comp2.month = 5;
comp2.day = 9;
comp2.hour = 20;
comp2.minute = 32;
//通过NSDateComponents所包含的时间字段的数值来恢复NSDate对象
NSDate* _date = [gregorian dateFromComponents:comp2];
NSLog(@"获取的日期为:%@", _date);
}
return 0;
}
运行结果:
定时器(NSTimer)
当程序需要让某个方法重复执行,可以借助OC中的定时器来完成。步骤如下:
- 调用NSTimer的scheduledTimerWithTimeInterval:invocation: repeats:或scheduledTimerWithTimeInterval:targe:selector:userInfo:repeats:类方法来创建NSTimer对象。调用该方法时,需要传入以下参数:
(1)timeInterval:指定每隔多少秒执行一次任务。
(2)invocation或target与selector:指定重复执行的任务。如果指定target和selector参数,则指定用某个对象的特定方法作为重复执行的任务;如果指定invocation参数,该参数需要传入一个NSInvocation对象,该对象也是封装target和selector的,其实也是指定用某个对象的特定方法作为重复执行的任务。
(3)userInfo:该参数用于传入额外的附加信息。
(4)repeats:该参数需要指定一个BOOL值,该参数控制是否需要重复执行任务。 - 为第一步的任务编写方法。
- 销毁定时器。调用定时器的invalidate方法即可。