OC学习12——字符串、日期、日历
前面主要学习了OC的基础知识,接下来将主要学习Foundation框架的一些常用类的常用方法。Foubdation框架是Cocoa编程、IOS编程的基础框架,包括代表字符串的NSString(代表字符序列不可变的字符串)、NSMutableString(代表字符序列可变的字符串),以及代表日期、时间的NSDate,关于日历的NSCalendar、NSDateComponents等常用类。
一、字符串
1、NSString代表字符序列不可变的字符串,即一旦NSString对象被创建,包含在这个对象中的字符序列就说不可改变的,直至这个对象被销毁。它的功能主要是处理字符串,主要功能如下:
- 穿件字符串
- 读取文件或网络URL来初始化字符串
- 获取字符串长度
- 获取字符串中的字符或字节
- 连接字符串
- 分割字符串
- 查找字符串内指定的字符和子串
- 替换字符串
- 比较字符串
- 字符串大小比较
- 字符串的大小写转换
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
unichar data[] = { , , , , , };
// 使用Unicode数值数组初始化字符串
NSString* str = [[NSString alloc]
initWithCharacters: data length:];
NSLog(@"%@" , str);
char* cstr = "Hello, iOS!";
// 将C风格的字符串转换为NSString对象
NSString* str2 = [NSString stringWithUTF8String:cstr];
NSLog(@"%@" , str2);
// 将字符串写入指定文件
[str2 writeToFile:@"myFile.txt"
atomically:YES
encoding:NSUTF8StringEncoding
error:nil];
// 读取文件内容,用文件内容初始化字符串
NSString* str3 = [NSString stringWithContentsOfFile:@"NSStringTest.m"
encoding:NSUTF8StringEncoding
error:nil];
NSLog(@"%@" , str3);
}
}
NSString对象的创建
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
NSString* str = @"Hello";
NSString* book = @"《疯狂iOS讲义》";
// 在str后面追加固定的字符串
// 原来字符串对象并不改变,只是将新生成的字符串重新赋给str指针变量
str = [str stringByAppendingString:@",iOS!"];
NSLog(@"%@" , str);
// 获取字符串对应的C风格字符串
const char* cstr = [str UTF8String];
NSLog(@"获取的C字符串:%s" , cstr);
// 在str后面追加带变量的字符串。
// 原来字符串对象并不改变,只是将新生成的字符串重新赋给str指针变量
str = [str stringByAppendingFormat:@"%@是一本非常不错的图书."
, book];
NSLog(@"%@" , str);
NSLog(@"str的字符个数为:%lu" , [str length]);
NSLog(@"str按UTF-8字符集解码后字节数为:%lu" , [str
lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
// 获取str的前10个字符组成的字符串
NSString* s1 = [str substringToIndex:];
NSLog(@"%@" , s1);
// 获取str的从第5个字符开始,与后面字符组成的字符串
NSString* s2 = [str substringFromIndex:];
NSLog(@"%@" , s2);
// 获取str从第5个字符开始,到第15个字符组成的字符串
NSString* s3 = [str substringWithRange:NSMakeRange(, )];
NSLog(@"%@" , s3);
// 获取iOS在str中出现位置
NSRange pos = [str rangeOfString:@"iOS"];
NSLog(@"iOS在str中出现的开始位置:%ld, 长度为:%ld"
, pos.location , pos.length);
// 将str的所有字符转为大写
str = [str uppercaseString];
NSLog(@"%@" , str);
}
}
NSString常用功能
2、NSMutableString代表字符序列可变的字符串,而且NSMutableString是NSString的子类,因此前面介绍的NSString所包含的方法,NSMutableString都可以直接使用,NSMutableString对象也可以直接当成NSString对象用。此外,NSMutableString还提供了很多可以修改字符串所包含字符序列的方法。
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
NSString* book = @"《疯狂iOS讲义》";
// 创建一个NSMutableString对象
NSMutableString* str = [NSMutableString
stringWithString:@"Hello"];
// 追加固定字符串
// 字符串所包含的字符序列本身发生了改变,因此无需重新赋值
[str appendString:@",iOS!"];
NSLog(@"%@" , str);
// 追加带变量的字符串
// 字符串所包含的字符序列本身发生了改变,因此无需重新赋值
[str appendFormat:@"%@是一本非常不错的图书." , book];
NSLog(@"%@" , str);
// 在指定位置插入字符串
// 字符串所包含的字符序列本身发生了改变,因此无需重新赋值
[str insertString:@"fkit.org" atIndex:];
NSLog(@"%@" , str);
// 删除从位置6到位置12的所有字符
[str deleteCharactersInRange:NSMakeRange(, )];
NSLog(@"%@" , str);
// 将从位置6到位置9的字符串替换成Objective-C
[str replaceCharactersInRange:NSMakeRange(, )
withString:@"Objetive-C"];
NSLog(@"%@" , str);
}
}
NSMutableString常用功能
二、日期与时间
1、NSDate对象代表日期和时间,OC既提供了类方法来创建NSDate对象,也提供了大量以init开头的方法来初始化NSDate对象。
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
// 获取代表当前日期、时间的NSDate
NSDate* date1 = [NSDate date];
NSLog(@"%@" , date1);
// 获取从当前时间开始,一天之后的日期
NSDate* date2 = [[NSDate alloc]
initWithTimeIntervalSinceNow:*];
NSLog(@"%@" , date2);
// 获取从当前时间开始,3天之前的日期
NSDate* date3 = [[NSDate alloc]
initWithTimeIntervalSinceNow: -**];
NSLog(@"%@" , date3);
// 获取从1970年1月1日开始,20年之后的日期
NSDate* date4 = [NSDate dateWithTimeIntervalSince1970:
* * * ];
NSLog(@"%@" , date4);
// 获取系统当前的Locale
NSLocale* cn = [NSLocale currentLocale];
// 获取NSDate在当前Locale下对应的字符串
NSLog(@"%@" , [date1 descriptionWithLocale:cn]);
// 获取两个日期之间较早的日期
NSDate* earlier = [date1 earlierDate:date2];
// 获取两个日期之间较晚的日期
NSDate* later = [date1 laterDate:date2];
// 比较两个日期,compare:方法返回NSComparisonResult枚举值
// 该枚举类型包含NSOrderedAscending、NSOrderedSame和
// NSOrderedDescending三个值,正如它们的名字暗示的。
// 分别代表调用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]);
}
}
NSDate初始化及常用方法
2、NSDateFormatter代表一个日期格式器,其功能就是完成NSDate和NSString之间的转换。使用NSDateFormatter完成NSDate和NSString之间的转换的步骤如下:
- 创建一个NSDateFormatter对象
- 调用NSDateFormatter的setDateStyle:、setTimeStyle:方法设置格式化日期、时间的风格。其中,日期、时间风格有如下几个枚举值:
- NSDateFormatterNoStyle:不显示日期、时间的风格
- NSDateFormatterShortStyle:显示“短”的日期、时间的风格
- NSDateFormatterMediumStyle:显示“中等”的日期、时间的风格
- NSDateFormatterLongStyle:显示“长”的日期、时间的风格
- NSDateFormatterFullStyle:显示“完整”的日期、时间的风格
- 如果打算使用自己的格式模版,则调用NSDateFormatter的setDateFormat:方法设置日期、时间模版即可。
3、如果需要将NSDate转化为NSString,则调用NSDateFormatter的stringFromDate:方法执行格式化即可;如果需要将NSString转化为NSDate,则调用NSDateFormatter的dateFromString:方法执行格式化即可。
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
// 需要被格式化的时间
// 获取从1970年1月1日开始,20年之后的日期
NSDate* dt = [NSDate dateWithTimeIntervalSince1970:
* * * ];
// 创建两个NSLocale,分别代表中国、美国
NSLocale* locales[] = {
[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]
, [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]};
NSDateFormatter* df[];
//为上面2个NSLocale创建8个DateFormat对象
for (int i = ; i < ; i++)
{
df[i * ] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * ] setDateStyle:NSDateFormatterShortStyle];
[df[i * ] setTimeStyle:NSDateFormatterShortStyle];
// 设置NSDateFormatter的NSLocale
[df[i * ] setLocale: locales[i]];
df[i * + ] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * + ] setDateStyle:NSDateFormatterMediumStyle];
[df[i * + ] setDateStyle:NSDateFormatterMediumStyle];
// 设置NSDateFormatter的NSLocale
[df[i * + ] setLocale: locales[i]];
df[i * + ] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * + ] setDateStyle:NSDateFormatterLongStyle];
[df[i * + ] setTimeStyle:NSDateFormatterLongStyle];
// 设置NSDateFormatter的NSLocale
[df[i * + ] setLocale: locales[i]];
df[i * + ] = [[NSDateFormatter alloc] init];
// 设置NSDateFormatter的日期、时间风格
[df[i * + ] setDateStyle:NSDateFormatterFullStyle];
[df[i * + ] setTimeStyle:NSDateFormatterFullStyle];
// 设置NSDateFormatter的NSLocale
[df[i * + ] setLocale: locales[i]];
}
for (int i = ; i < ; i++)
{
switch (i)
{
case :
NSLog(@"-------中国日期格式--------");
break;
case :
NSLog(@"-------美国日期格式--------");
break;
}
NSLog(@"SHORT格式的日期格式:%@"
, [df[i * ] stringFromDate: dt]);
NSLog(@"MEDIUM格式的日期格式:%@"
, [df[i * + ] stringFromDate: dt]);
NSLog(@"LONG格式的日期格式:%@"
, [df[i * + ] stringFromDate: dt]);
NSLog(@"FULL格式的日期格式:%@"
, [df[i * + ] stringFromDate: dt]);
}
NSDateFormatter* df2 = [[NSDateFormatter alloc] init];
// 设置自定义的格式器模板
[df2 setDateFormat:@"公元yyyy年MM月DD日 HH时mm分"];
// 执行格式化
NSLog(@"%@" , [df2 stringFromDate:dt]);
NSString* dateStr = @"2013-03-02";
NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
// 根据日期字符串的格式设置格式模板
[df3 setDateFormat:@"yyyy-MM-dd"];
// 将字符串转换为NSDate对象
NSDate* date2 = [df3 dateFromString: dateStr];
NSLog(@"%@" , date2);
}
}
NSDateFormatter常用功能
4、Foundation框架还提供了NSCalendar对象来处理NSDate对象所包含的各个字段的数据,NSCalendar主要包含如下两个方法:
- (NSDateComponents *) components:fromDate::从NSDate中提取年、月、日、时、分、秒各时间字段信息
- dateFromComponents:(NSDateComponents *)comps:使用comps对象包含的年、月、日、时、分、秒各时间字段信息来创建NSDate对象
上面两个方法都用到了NSDateComponents对象,该对象是专门用于封装年、月、日、时、分、秒各时间字段信息的日期组件类。该对象十分简单,它只包含了对year、month、day、hour、minute、second、week、weekday等各字段的setter和getter方法。
从NSDate中分开获取各时间字段的数值的步骤如下:
- 创建NSCalendar对象
- 调用NSCalendar的components:fromDate:方法获取数值,返回一个NSDateComponents对象
- 调用NSDateComponents的getter方法获取个时间字段的数值
使用个时间字段的数值来初始化NSDate对象的步骤如下:
- 创建NSCalendar对象
- 创建一个NSDateComponents对象,并用setter方法对各个字段进行赋值
- 调用NSCalendar的dateFromComponents:方法初始化NSDate对象,该方法返回一个NSDate对象
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
// 获取代表公历的Calendar对象
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
// 获取当前日期
NSDate* dt = [NSDate date];
// 定义一个时间字段的旗标,指定将会获取指定年、月、日、时、分、秒的信息
unsigned unitFlags = NSYearCalendarUnit |
NSMonthCalendarUnit | NSDayCalendarUnit |
NSHourCalendarUnit | NSMinuteCalendarUnit |
NSSecondCalendarUnit | NSWeekdayCalendarUnit;
// 获取不同时间字段的信息
NSDateComponents* comp = [gregorian components: unitFlags
fromDate:dt];
// 获取各时间字段的数值
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 = ;
comp2.month = ;
comp2.day = ;
comp2.hour = ;
comp2.minute = ;
// 通过NSDateComponents所包含的时间字段的数值来恢复NSDate对象
NSDate *date = [gregorian dateFromComponents:comp2];
NSLog(@"获取的日期为:%@" , date);
}
}
NSCalendar与NSDate之间的转换
三、对象复制
1、NSObject类提供了copy和mutableCopy方法,通过这两个方法即可复制已有对象的副本。
- copy方法用于复制对象的副本。通常来说,copy方法返回的副本对象总是不可修改的,即使该原始对象是可修改。
- mutableCopy方法用于复制对象的可变副本,通常来说,mutableCopy方法返回的副本对象总是可修改的(MutableString等),即使该原始对象是不可修改。
- 无论如何,copy和mutableCopy方法返回的总是原对象的副本,方程序对复制的对象的副本进行修改时,原对象通常不受影响。
#import <Foundation/Foundation.h> int main(int argc , char * argv[])
{
@autoreleasepool{
NSMutableString* book = [NSMutableString
stringWithString:@"疯狂iOS讲义"];
// 复制book字符串的可变副本
NSMutableString* bookCopy = [book mutableCopy];
// 对副本修改,对原字符串没有任何影响
[bookCopy replaceCharactersInRange:
NSMakeRange(, )
withString:@"Android"];
// 此处看到原字符串的值并没有改变
NSLog(@"book的值为:%@" , book);
// 字符串副本发生了改变。
NSLog(@"bookCopy的值为:%@" , bookCopy);
NSString* str = @"fkit";
// 复制str(不可变字符串)的可变副本
NSMutableString* strCopy = [str mutableCopy]; //①
// 向可变字符串后面追加字符串
[strCopy appendString:@".org"];
NSLog(@"%@" , strCopy);
// 调用book(可变字符串)的copy方法,程序返回一个不可修改的副本
NSMutableString* bookCopy2 = [book copy]; //②
// 由于bookCopy2是不可修改的,因此下面代码将会出现错误
[bookCopy2 appendString:@"aa"];
}
}
copy与mutableCopy的区别
2、当程序调用对象的copy或mutableCopy方法时,实际上程序底层需要调用copyWithZone:或mutableCopyWithZone:方法来完成实际的复制工作,copy或mutableCopy方法的返回值实际上就是copyWithZone:或mutableCopyWithZone:方法的返回值。而copyWithZone:和mutableCopyWithZone:方法并不是NSObject的方法,而是NSCopy和NSMutableCopy协议中的方法。所以,对于哦我们自定义的类,如果只是简单地继承自NSObject类,在程序中如果直接调用该自定义类的copy或mutableCopy方法时,编译是没有问题的,但是在运行时会出现问题,原因就在于自定义类没有实现NSCopy和NSMutableCopy协议中copyWithZone:和mutableCopyWithZone:方法。所以,如果我们自定义类需要实现copy或mutableCopy方法,则通常需要做以下事情:
- 让该类实现NSCopy和NSMutableCopy协议
- 让该类实现copyWithZone:和mutableCopyWithZone:方法
#import <Foundation/Foundation.h> @interface FKDog : NSObject <NSCopying>
@property (nonatomic , strong) NSMutableString* name;
@property (nonatomic , assign) int age;
@end
#import "FKDog.h" @implementation FKDog
- (id)copyWithZone:(NSZone*)zone
{
NSLog(@"--执行copyWithZone--");
// 使用zone参数创建FKDog对象
FKDog* dog = [[[self class] allocWithZone:zone] init];
dog.name = self.name;
dog.age = self.age;
return dog;
} @end
#import <Foundation/Foundation.h>
#import "FKDog.h" int main(int argc , char * argv[])
{
@autoreleasepool{
// 创建一个FKDog对象
FKDog* dog1 = [FKDog new];
dog1.name = [NSMutableString stringWithString:@"旺财"];
dog1.age = ;
// 复制副本
FKDog* dog2 = [dog1 copy];
// 复制对象的可变副本
// FKDog* dog2 = [dog1 mutableCopy];
dog2.name = [NSMutableString stringWithString:@"snoopy"];
dog2.age = ;
NSLog(@"dog1的名字为:%@" , dog1.name);
NSLog(@"dog1的年龄为:%d" , dog1.age);
NSLog(@"dog2的名字为:%@" , dog2.name);
NSLog(@"dog2的年龄为:%d" , dog2.age);
}
}
3、深复制和浅复制 Objective-C中的深拷贝和浅拷贝 其实OC中深复制和浅复制的概念与在Java、C++中的概念是一致的。简单来说就是深复制取完全的一个新的副本对象,副本对象与原对象没有任何交集,而浅复制则是原对象与副本对象之间还有交集。所谓交集指的是存在某一个指针变量指向同一个对象的情况。
- 浅复制:当对象的属性是指针变量时,如果程序只是复制该指针的地址,而不是真正赋值指针所指向的对象,这种方式就被称之为浅复制。
- 深复制:深复制不仅会赋值对象本身,还会递归赋值每个指针类型的属性,直到两个对象没有任何共用的部分。
OC学习12——字符串、日期、日历的更多相关文章
- java学习笔记之日期日历类
java学习笔记之日期日历 Date日期类概述: 表示特定的瞬间,精确到毫秒 Date类的构造方法: 1.空参数构造方法 Date date = new Date(); 获取到当前操作系统中的时间和日 ...
- 【OC学习-12】什么是类的继承?为什么要继承?以及继承里面的注意事项
(1)怎样实现类的继承? //之前的继承根类,如类ASStudent继承自根类 @interface ASStudent:NSObject{ } @end //如今继承现有自己定义的类,如ASStud ...
- (转载)OC学习篇之---Foundation框架中的其他类(NSNumber,NSDate,NSExcetion)
前一篇说到了Foundation框架中的NSDirctionary类,这一一篇来看一下Foundation的其他常用的类:NSNumber,NSDate,NSException. 注:其实按照Java ...
- Java SE学习之printf 日期转换符
本文是学习网络上的文章时的总结,感谢大家无私的分享. System.out.printf()方法能够对日期做处理输出. 相应列表 转换符 类型 举例 c 完整的日期和时间 Mon Feb 09 18: ...
- OC学习篇之---Foundation框架中的其他类(NSNumber,NSDate,NSExcetion)
1.NSNumber 这个类主要是用来封装基本类型的,说到这里,就不得不说一下了: OC中的集合是不允许存入基本类型的,所以NSNumber类就诞生了,需要将基本类型封装一下,然后存进去,这个类似于J ...
- 一款简洁大气的jquery日期日历插件
本jquery插件名为manhuaDate,暂时只支持jquery 1.9.0以下版本,比如jquery-1.8.3.min.js 查看效果网址:http://keleyi.com/a/bjad/em ...
- JavaScript学习12 JS中定义对象的几种方式
JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...
- (转载)OC学习篇之---第一个程序HelloWorld
之前的一片文章简单的介绍了OC的相关概述,从这篇开始我们就开始学习OC的相关知识了,在学习之前,个人感觉需要了解的其他的两门语言:一个是C/C++,一个是面向对象的语言(当然C++就是面向对象,不过这 ...
- (转载)OC学习篇之---概述
前言 终于开启了OC的学习篇了,之前由于工作上的事,学习就一直搁浅了,不过最近由于各种原因,感觉必须要开启iOS的开发旅程了,不然就老了.因为之前一直是做Android的,所以学习iOS来就没那么费劲 ...
随机推荐
- 说说css中pt、px、em、rem都扮演了什么角色
前段时间,终于仔仔细细的把pt.px.em.rem了解了一遍,简单整理了一下做个记录. pt.px.em.rem都是什么 pt单位名称为点(Point),绝对长度单位.现在网页中出现得很少甚至不出现, ...
- node学习笔记(二)(ajax方式向node后台提交数据)
通过ajax向node后台提交数据过程(附手写前后台代码),并总结post与get的区别 POST 前台代码 //CSS简单给点样式 <style> form{ width: 200px; ...
- Ipython自动导入Numpy,pandas等模块
一.引言 最近在学习numpy,书上要求安装一个Ipythpn,可以自动导入Numpy,pandas等数据分析的模块,可是当我安装后,并不能自动导入numpy模块,还需要自己import.我就去查了一 ...
- php简单实现发微博动态
首先,肯定是注册成为开发者新浪微博开放平台 选择网站应用,填写一些基本信息 填完后在'我的应用'中,会看到刚创建的应用信息,我们只是简单的测试一下,所以其他复杂的注册信息都不用填写,有这些就够了 很重 ...
- 深入理解php底层:php生命周期
1.PHP的运行模式: PHP两种运行模式是WEB模式.CLI模式.无论哪种模式,PHP工作原理都是一样的,作为一种SAPI运行. 1.当我们在终端敲入php这个命令的时候,它使用的是CLI. 它就像 ...
- rabbitmq(中间消息代理)在python中的使用
在之前的有关线程,进程的博客中,我们介绍了它们各自在同一个程序中的通信方法.但是不同程序,甚至不同编程语言所写的应用软件之间的通信,以前所介绍的线程.进程队列便不再适用了:此种情况便只能使用socke ...
- Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置
背景: 前天开源了框架:开源:Sagit.Framework For IOS 开发框架 所以注定要追补一套开发教程了,所以尽量抽空了!!! 步骤 1:下载框架源码 GitHub:https://git ...
- 通过Javascript调用微软认知服务情感检测接口的两种实现方式
这是今天在黑客松现场写的代码.我们的项目需要调用认知服务的情感识别接口.官方提供了一种方式,就是从一个远程图片进行识别.我另外写了一个从本地文件读取并上传进行识别的例子. 官方文档,请参考 https ...
- hicoder1142 三分求极值
在直角坐标系中有一条抛物线y=ax^2+bx+c和一个点P(x,y),求点P到抛物线的最短距离d. 我们代入公式,有: $d = min(\sqrt{(X - x)^2+(aX^2+bX+c-y)^2 ...
- tyvj4866 摆摊
这分送的真慷慨,我随手打了个莫队,就90了.... 90分代码: #include<bits/stdc++.h> using namespace std; #define MAXN 100 ...