zoukankan      html  css  js  c++  java
  • OC学习12——字符串、日期、日历

      前面主要学习了OC的基础知识,接下来将主要学习Foundation框架的一些常用类的常用方法。Foubdation框架是Cocoa编程、IOS编程的基础框架,包括代表字符串的NSString(代表字符序列不可变的字符串)、NSMutableString(代表字符序列可变的字符串),以及代表日期、时间的NSDate,关于日历的NSCalendar、NSDateComponents等常用类。

    一、字符串

    1、NSString代表字符序列不可变的字符串,即一旦NSString对象被创建,包含在这个对象中的字符序列就说不可改变的,直至这个对象被销毁。它的功能主要是处理字符串,主要功能如下:

    • 穿件字符串
    • 读取文件或网络URL来初始化字符串
    • 获取字符串长度
    • 获取字符串中的字符或字节
    • 连接字符串
    • 分割字符串
    • 查找字符串内指定的字符和子串
    • 替换字符串
    • 比较字符串
    • 字符串大小比较
    • 字符串的大小写转换
     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         unichar data[6] = {97 , 98 , 99 , 100 , 101, 102};
     7         // 使用Unicode数值数组初始化字符串
     8         NSString* str = [[NSString alloc]
     9             initWithCharacters: data length:6];
    10         NSLog(@"%@" , str);
    11         char* cstr = "Hello, iOS!";
    12         // 将C风格的字符串转换为NSString对象
    13         NSString* str2 = [NSString stringWithUTF8String:cstr];
    14         NSLog(@"%@" , str2);
    15         // 将字符串写入指定文件 
    16         [str2 writeToFile:@"myFile.txt"
    17             atomically:YES 
    18             encoding:NSUTF8StringEncoding
    19             error:nil];
    20         // 读取文件内容,用文件内容初始化字符串
    21         NSString* str3 = [NSString stringWithContentsOfFile:@"NSStringTest.m"
    22             encoding:NSUTF8StringEncoding 
    23             error:nil];
    24         NSLog(@"%@" , str3);
    25     }
    26 }
    NSString对象的创建
     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         NSString* str = @"Hello";
     7         NSString* book = @"《疯狂iOS讲义》";
     8         // 在str后面追加固定的字符串
     9         // 原来字符串对象并不改变,只是将新生成的字符串重新赋给str指针变量
    10         str = [str stringByAppendingString:@",iOS!"];
    11         NSLog(@"%@" , str);
    12         // 获取字符串对应的C风格字符串
    13         const char* cstr = [str UTF8String];
    14         NSLog(@"获取的C字符串:%s" , cstr);
    15         // 在str后面追加带变量的字符串。
    16         // 原来字符串对象并不改变,只是将新生成的字符串重新赋给str指针变量
    17         str = [str stringByAppendingFormat:@"%@是一本非常不错的图书."
    18             , book];
    19         NSLog(@"%@" , str);
    20         NSLog(@"str的字符个数为:%lu" , [str length]);
    21         NSLog(@"str按UTF-8字符集解码后字节数为:%lu" , [str 
    22             lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
    23         // 获取str的前10个字符组成的字符串
    24         NSString* s1 = [str substringToIndex:10];
    25         NSLog(@"%@" , s1);
    26         // 获取str的从第5个字符开始,与后面字符组成的字符串
    27         NSString* s2 = [str substringFromIndex:5];
    28         NSLog(@"%@" , s2);    
    29         // 获取str从第5个字符开始,到第15个字符组成的字符串
    30         NSString* s3 = [str substringWithRange:NSMakeRange(5, 15)];
    31         NSLog(@"%@" , s3);
    32         // 获取iOS在str中出现位置
    33         NSRange pos = [str rangeOfString:@"iOS"];
    34         NSLog(@"iOS在str中出现的开始位置:%ld, 长度为:%ld"
    35             , pos.location , pos.length);
    36         // 将str的所有字符转为大写
    37         str = [str uppercaseString];
    38         NSLog(@"%@" , str);
    39     }
    40 }
    NSString常用功能

    2、NSMutableString代表字符序列可变的字符串,而且NSMutableString是NSString的子类,因此前面介绍的NSString所包含的方法,NSMutableString都可以直接使用,NSMutableString对象也可以直接当成NSString对象用。此外,NSMutableString还提供了很多可以修改字符串所包含字符序列的方法。

     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         NSString* book = @"《疯狂iOS讲义》";
     7         // 创建一个NSMutableString对象
     8         NSMutableString* str = [NSMutableString 
     9             stringWithString:@"Hello"];
    10         // 追加固定字符串
    11         // 字符串所包含的字符序列本身发生了改变,因此无需重新赋值
    12         [str appendString:@",iOS!"];
    13         NSLog(@"%@" , str);
    14         // 追加带变量的字符串
    15         // 字符串所包含的字符序列本身发生了改变,因此无需重新赋值
    16         [str appendFormat:@"%@是一本非常不错的图书." , book];
    17         NSLog(@"%@" , str);
    18         // 在指定位置插入字符串
    19         // 字符串所包含的字符序列本身发生了改变,因此无需重新赋值
    20         [str insertString:@"fkit.org" atIndex:6];
    21         NSLog(@"%@" , str);
    22         // 删除从位置6到位置12的所有字符
    23         [str deleteCharactersInRange:NSMakeRange(6, 12)];
    24         NSLog(@"%@" , str);
    25         // 将从位置6到位置9的字符串替换成Objective-C
    26         [str replaceCharactersInRange:NSMakeRange(6, 9)
    27             withString:@"Objetive-C"];
    28         NSLog(@"%@" , str);
    29     }
    30 }
    NSMutableString常用功能

    二、日期与时间

    1、NSDate对象代表日期和时间,OC既提供了类方法来创建NSDate对象,也提供了大量以init开头的方法来初始化NSDate对象。

     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         // 获取代表当前日期、时间的NSDate
     7         NSDate* date1 = [NSDate date];
     8         NSLog(@"%@" , date1);
     9         // 获取从当前时间开始,一天之后的日期
    10         NSDate* date2 = [[NSDate alloc]
    11             initWithTimeIntervalSinceNow:3600*24];
    12         NSLog(@"%@" , date2);
    13         // 获取从当前时间开始,3天之前的日期
    14         NSDate* date3 = [[NSDate alloc]
    15             initWithTimeIntervalSinceNow: -3*3600*24];
    16         NSLog(@"%@" , date3);
    17         // 获取从1970年1月1日开始,20年之后的日期    
    18         NSDate* date4 = [NSDate dateWithTimeIntervalSince1970:
    19             3600 * 24 * 366 * 20];
    20         NSLog(@"%@" , date4);
    21         // 获取系统当前的Locale
    22         NSLocale* cn = [NSLocale currentLocale];
    23         // 获取NSDate在当前Locale下对应的字符串
    24         NSLog(@"%@" , [date1 descriptionWithLocale:cn]);
    25         // 获取两个日期之间较早的日期
    26         NSDate* earlier = [date1 earlierDate:date2];
    27         // 获取两个日期之间较晚的日期
    28         NSDate* later = [date1 laterDate:date2];
    29         // 比较两个日期,compare:方法返回NSComparisonResult枚举值
    30         // 该枚举类型包含NSOrderedAscending、NSOrderedSame和
    31         // NSOrderedDescending三个值,正如它们的名字暗示的。
    32         // 分别代表调用compare:的日期位于被比较日期之前、相同、之后。
    33         switch ([date1 compare:date3])
    34         {
    35             case NSOrderedAscending:
    36                 NSLog(@"date1位于date3之前");
    37                 break;
    38             case NSOrderedSame:
    39                 NSLog(@"date1与date3日期相等");
    40                 break;
    41             case NSOrderedDescending:
    42                 NSLog(@"date1位于date3之后");
    43                 break;
    44         }
    45         // 获取两个时间之间的时间差
    46         NSLog(@"date1与date3之间时间差%g秒" 
    47             , [date1 timeIntervalSinceDate:date3]);
    48         // 获取指定时间与现在的时间差
    49         NSLog(@"date2与现在间时间差%g秒" 
    50             , [date2 timeIntervalSinceNow]);
    51     }
    52 }
    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:方法执行格式化即可。

     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         // 需要被格式化的时间
     7         // 获取从1970年1月1日开始,20年之后的日期    
     8         NSDate* dt = [NSDate dateWithTimeIntervalSince1970:
     9             3600 * 24 * 366 * 20];
    10         // 创建两个NSLocale,分别代表中国、美国
    11         NSLocale* locales[] = {
    12             [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]
    13             , [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]};
    14         NSDateFormatter* df[8];
    15         //为上面2个NSLocale创建8个DateFormat对象
    16         for (int i = 0 ; i < 2 ; i++)
    17         {
    18             df[i * 4] = [[NSDateFormatter alloc] init];
    19             // 设置NSDateFormatter的日期、时间风格
    20             [df[i * 4] setDateStyle:NSDateFormatterShortStyle];
    21             [df[i * 4] setTimeStyle:NSDateFormatterShortStyle];
    22             // 设置NSDateFormatter的NSLocale
    23             [df[i * 4] setLocale: locales[i]];
    24             df[i * 4 + 1] = [[NSDateFormatter alloc] init];    
    25             // 设置NSDateFormatter的日期、时间风格            
    26             [df[i * 4 + 1] setDateStyle:NSDateFormatterMediumStyle];
    27             [df[i * 4 + 1] setDateStyle:NSDateFormatterMediumStyle];
    28             // 设置NSDateFormatter的NSLocale
    29             [df[i * 4 + 1] setLocale: locales[i]];
    30             df[i * 4 + 2] = [[NSDateFormatter alloc] init];    
    31             // 设置NSDateFormatter的日期、时间风格            
    32             [df[i * 4 + 2] setDateStyle:NSDateFormatterLongStyle];
    33             [df[i * 4 + 2] setTimeStyle:NSDateFormatterLongStyle];
    34             // 设置NSDateFormatter的NSLocale
    35             [df[i * 4 + 2] setLocale: locales[i]];
    36             df[i * 4 + 3] = [[NSDateFormatter alloc] init];    
    37             // 设置NSDateFormatter的日期、时间风格            
    38             [df[i * 4 + 3] setDateStyle:NSDateFormatterFullStyle];
    39             [df[i * 4 + 3] setTimeStyle:NSDateFormatterFullStyle];
    40             // 设置NSDateFormatter的NSLocale
    41             [df[i * 4 + 3] setLocale: locales[i]];
    42         }
    43         for (int i = 0 ; i < 2 ; i++)
    44         {
    45             switch (i)
    46             {
    47                 case 0:
    48                     NSLog(@"-------中国日期格式--------");
    49                     break;
    50                 case 1:
    51                     NSLog(@"-------美国日期格式--------");
    52                     break;
    53             }
    54             NSLog(@"SHORT格式的日期格式:%@"
    55                 , [df[i * 4] stringFromDate: dt]);
    56             NSLog(@"MEDIUM格式的日期格式:%@"
    57                 , [df[i * 4 + 1] stringFromDate: dt]);
    58             NSLog(@"LONG格式的日期格式:%@"
    59                 , [df[i * 4 + 2] stringFromDate: dt]);
    60             NSLog(@"FULL格式的日期格式:%@"
    61                 , [df[i * 4 + 3] stringFromDate: dt]);
    62         }
    63         NSDateFormatter* df2 = [[NSDateFormatter alloc] init];
    64         // 设置自定义的格式器模板
    65         [df2 setDateFormat:@"公元yyyy年MM月DD日 HH时mm分"];
    66         // 执行格式化
    67         NSLog(@"%@" , [df2 stringFromDate:dt]);
    68         NSString* dateStr = @"2013-03-02";
    69         NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
    70         // 根据日期字符串的格式设置格式模板    
    71         [df3 setDateFormat:@"yyyy-MM-dd"];
    72         // 将字符串转换为NSDate对象
    73         NSDate* date2 = [df3 dateFromString: dateStr];
    74         NSLog(@"%@" , date2);    
    75     }
    76 }
    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中分开获取各时间字段的数值的步骤如下:

    1. 创建NSCalendar对象
    2. 调用NSCalendar的components:fromDate:方法获取数值,返回一个NSDateComponents对象
    3. 调用NSDateComponents的getter方法获取个时间字段的数值

      使用个时间字段的数值来初始化NSDate对象的步骤如下:

    1. 创建NSCalendar对象
    2. 创建一个NSDateComponents对象,并用setter方法对各个字段进行赋值
    3. 调用NSCalendar的dateFromComponents:方法初始化NSDate对象,该方法返回一个NSDate对象
     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         // 获取代表公历的Calendar对象
     7         NSCalendar *gregorian = [[NSCalendar alloc]
     8             initWithCalendarIdentifier:NSGregorianCalendar];
     9         // 获取当前日期 
    10         NSDate* dt = [NSDate date];
    11         // 定义一个时间字段的旗标,指定将会获取指定年、月、日、时、分、秒的信息
    12         unsigned unitFlags = NSYearCalendarUnit | 
    13             NSMonthCalendarUnit |  NSDayCalendarUnit |
    14             NSHourCalendarUnit |  NSMinuteCalendarUnit |
    15             NSSecondCalendarUnit | NSWeekdayCalendarUnit;
    16         // 获取不同时间字段的信息
    17         NSDateComponents* comp = [gregorian components: unitFlags 
    18             fromDate:dt];
    19         // 获取各时间字段的数值
    20         NSLog(@"现在是%ld年" , comp.year);
    21         NSLog(@"现在是%ld月 " , comp.month);
    22         NSLog(@"现在是%ld日" , comp.day);
    23         NSLog(@"现在是%ld时" , comp.hour);
    24         NSLog(@"现在是%ld分" , comp.minute);
    25         NSLog(@"现在是%ld秒" , comp.second);
    26         NSLog(@"现在是星期%ld" , comp.weekday);
    27         
    28         // 再次创建一个NSDateComponents对象
    29         NSDateComponents* comp2 = [[NSDateComponents alloc] 
    30             init];
    31         // 设置各时间字段的数值
    32         comp2.year = 2013;
    33         comp2.month = 4;
    34         comp2.day = 5;
    35         comp2.hour = 18;
    36         comp2.minute = 34;
    37         // 通过NSDateComponents所包含的时间字段的数值来恢复NSDate对象
    38         NSDate *date = [gregorian dateFromComponents:comp2];
    39         NSLog(@"获取的日期为:%@" , date);
    40     }
    41 }
    NSCalendar与NSDate之间的转换

    三、对象复制

    1、NSObject类提供了copy和mutableCopy方法,通过这两个方法即可复制已有对象的副本。

    • copy方法用于复制对象的副本。通常来说,copy方法返回的副本对象总是不可修改的,即使该原始对象是可修改。
    • mutableCopy方法用于复制对象的可变副本,通常来说,mutableCopy方法返回的副本对象总是可修改的(MutableString等),即使该原始对象是不可修改。
    • 无论如何,copy和mutableCopy方法返回的总是原对象的副本,方程序对复制的对象的副本进行修改时,原对象通常不受影响
     1 #import <Foundation/Foundation.h>
     2 
     3 int main(int argc , char * argv[])
     4 {
     5     @autoreleasepool{
     6         NSMutableString* book = [NSMutableString 
     7             stringWithString:@"疯狂iOS讲义"];
     8         // 复制book字符串的可变副本
     9         NSMutableString* bookCopy = [book mutableCopy];
    10         // 对副本修改,对原字符串没有任何影响
    11         [bookCopy replaceCharactersInRange:
    12             NSMakeRange(2, 3)
    13             withString:@"Android"];
    14         // 此处看到原字符串的值并没有改变
    15         NSLog(@"book的值为:%@" , book);
    16         // 字符串副本发生了改变。
    17         NSLog(@"bookCopy的值为:%@" , bookCopy);
    18         NSString* str = @"fkit";
    19         // 复制str(不可变字符串)的可变副本
    20         NSMutableString* strCopy = [str mutableCopy]; //21         // 向可变字符串后面追加字符串
    22         [strCopy appendString:@".org"];
    23         NSLog(@"%@" , strCopy);
    24         // 调用book(可变字符串)的copy方法,程序返回一个不可修改的副本
    25         NSMutableString* bookCopy2 = [book copy]; //26         // 由于bookCopy2是不可修改的,因此下面代码将会出现错误
    27         [bookCopy2 appendString:@"aa"];    
    28     }
    29 }
    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:方法
    1 #import <Foundation/Foundation.h>
    2 
    3 @interface FKDog : NSObject <NSCopying>
    4 @property (nonatomic , strong) NSMutableString* name;
    5 @property (nonatomic , assign) int age;
    6 @end
     1 #import "FKDog.h"
     2 
     3 @implementation FKDog
     4 - (id)copyWithZone:(NSZone*)zone
     5 {
     6     NSLog(@"--执行copyWithZone--");
     7     // 使用zone参数创建FKDog对象
     8     FKDog* dog = [[[self class] allocWithZone:zone] init];
     9     dog.name = self.name;
    10     dog.age = self.age;
    11     return dog;
    12 }
    13 
    14 @end
     1 #import <Foundation/Foundation.h>
     2 #import "FKDog.h"
     3 
     4 int main(int argc , char * argv[])
     5 {
     6     @autoreleasepool{
     7         // 创建一个FKDog对象
     8         FKDog* dog1 = [FKDog new];
     9         dog1.name = [NSMutableString stringWithString:@"旺财"];
    10         dog1.age = 20;
    11         // 复制副本
    12         FKDog* dog2 = [dog1 copy];
    13         // 复制对象的可变副本
    14 //        FKDog* dog2 = [dog1 mutableCopy];
    15         dog2.name = [NSMutableString stringWithString:@"snoopy"];
    16         dog2.age = 12;
    17         NSLog(@"dog1的名字为:%@" , dog1.name);
    18         NSLog(@"dog1的年龄为:%d" , dog1.age);
    19         NSLog(@"dog2的名字为:%@" , dog2.name);
    20         NSLog(@"dog2的年龄为:%d" , dog2.age);
    21     }
    22 }

    3、深复制和浅复制  Objective-C中的深拷贝和浅拷贝 其实OC中深复制和浅复制的概念与在Java、C++中的概念是一致的。简单来说就是深复制取完全的一个新的副本对象,副本对象与原对象没有任何交集,而浅复制则是原对象与副本对象之间还有交集。所谓交集指的是存在某一个指针变量指向同一个对象的情况。

    • 浅复制:当对象的属性是指针变量时,如果程序只是复制该指针的地址,而不是真正赋值指针所指向的对象,这种方式就被称之为浅复制。
    • 深复制:深复制不仅会赋值对象本身,还会递归赋值每个指针类型的属性,直到两个对象没有任何共用的部分。
  • 相关阅读:
    vue使用百度统计埋点
    修改JAVA字节码
    由前序遍历和中序遍历构建二叉树-Python
    二叉树的最大深度-Python
    二叉树的层序遍历-Python
    判断是否是对称二叉搜索树
    什么是主动学习方法
    验证二叉搜索树-Python
    DevExpress如何汉化XAF
    python install 失败?
  • 原文地址:https://www.cnblogs.com/mukekeheart/p/7380236.html
Copyright © 2011-2022 走看看