【iOS】—— Foundation框架(一)- 字符串(NSString与NSMutableString)

7.1 字符串(NSString与NSMutableString)

NSString:字符序列不可变的字符串
NSMutableString:字符序列可变的字符串


7.1.1 创建字符串

NSString功能:
  • 创建字符串: 创建字符串既可以使用以init开头的实例方法,也可以使用以string开 头的类方法,当然也可以直接使用@“”的形式给出字符串直接量
  • 读取文件或网络URL来初始化字符串
  • 将字符串内容写入文件或URL
  • 获取字符串长度,既可以获取字符串内包括的字符个数,也可以获取字符串包括的字节个数
  • 获取字符串中的字符或字节,既可获取指定位置的字符,也可以获取指定范围的字符
  • 获取字符串对应的C风格字符串
  • 连接字符串
  • 分隔字符串
  • 查找字符串内指定的字符和子串替换字符串
  • 比较字符串
  • 字符串大小比较
  • 对字符串中的字符进行大小写转换
NSString的常见用法:
        unichar data[6] = {97, 98, 99, 100, 101, 102};
        //使用Unicode数值数组初始化字符串
        NSString* str = [[NSString alloc] initWithCharacters:data length:6];
        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:@"myFile.txt" encoding:NSUTF8StringEncoding error:nil];
        NSLog(@"%@", str3);

输出结果为:
2


7.1.2 NSString的常用功能

NSString的常见用法:
        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:10];
        NSLog(@"%@", s1);
        //获取str第5个字符之后的字符串
        NSString* s2 = [str substringFromIndex:5];
        NSLog(@"%@", s2);
        //获取str从第5个字符之后,数15个字符组成的字符串
        NSString* s3 = [str substringWithRange:NSMakeRange(5, 15)];
        NSLog(@"%@", s3);
        //获取iOS在str中出现的位置
        NSRange pos = [str rangeOfString:@"iOS"];
        NSLog(@"iOS在str中出现的开始位置:%ld,长度为:%ld", pos.location, pos.length);
        //将str的所有字符大写
        str = [str uppercaseString];
        NSLog(@"%@", str);

输出结果为:
2

NSRange:

NSRange并不是一个类,它只是一个结构体,它包括了location和length两个unsigned int整型值,分别代表起始位置和长度。Objecetive-C还提供了NSMakeRange()函数来创建NSRange变量。


7.1.3 可变字符串(NSMutableString)

NSString类是不可变的类,即一旦NSSting对象被创建,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
NSMutableString对象则代表一个字符串序列可变的字符串,而且NSMutableString是NSString的子类,因此NSString的方法,NSMutableString都可以直接使用,NSMutableString对象也可以直接当成NSString对象使用。
NSMutableString提供:appendFormat:、appendString:、deleteCharactersInRange:、insertString:atIndex:、replaceCharactersInRange:withString:、replaceOccurrencesOfString:options:range:、setString:方即可改变该字符串所包含的字符序列。

NSMutableString常见用法:
        NSString* book =@"《疯狂iOS讲义》";
        //创建一个NSMutableString对象
        NSMutableString* str = [NSMutableString stringWithString:@"Hello"];
        //追加固定的字符串
        //字符串所包含的字符序列本身发生了改变,因此无须重新赋值
        [str appendString:@",iOS!"];
        NSLog(@"%@", str);
        //追加带变量的字符串
        //字符串所包含的字符序列本身发生了改变,因此无须重新赋值
        [str appendFormat:@"%@是一本非常不错的图书。", book];
        NSLog(@"%@", str);
        //在指定位置插入字符串
        //字符串所包含的字符序列本身发生了改变,因此无须重新赋值
        [str insertString:@"fkit.org" atIndex:6];
        NSLog(@"%@", str);
        //删除从位置6开始之后的12个字符
        [str deleteCharactersInRange:NSMakeRange(6, 12)];
        NSLog(@"%@", str);
        //将从位置6开始数9个字符将这9个字符替换成Objective-C
        [str replaceCharactersInRange:NSMakeRange(6, 9) withString:@"Objective-C"];
        NSLog(@"%@", str);

输出结果为:
w


7.2 日期与时间

Objective-C为处理日期、时间提供了NSDate、NSCalendar对象,还提供了日期格式器来处理日期与字符串之间的转换。


7.2.1 日期与时间(NSDate)

NSDate对象代表日期与时间,Objective-C中既提供了类方法来创建NSDate对象,也提供了大量以init开头的方法来初始化NSDate对象。

NSDate常见方法的用途:
        //获取代表当前日期、时间的NSDate
        NSDate* date1 = [NSDate date];
        NSLog(@"%@", date1);
        //获取从当前时间开始,一天之后的日期
        NSDate* date2 = [[NSDate alloc]
                         initWithTimeIntervalSinceNow:3600 * 24];
        NSLog(@"%@", date2);
        //获取从当前时间开始,3天之前的日期
        NSDate* date3 = [[NSDate alloc]
                         initWithTimeIntervalSinceNow:-3 * 3600 * 24];
        NSLog(@"%@", date3);
        //获取从1970年1月1日开始,20年之后的日期
        NSDate* date4 = [NSDate dateWithTimeIntervalSince1970:3600 * 24 * 366 * 20];
        NSLog(@"%@", date4);
        //获取系统当前的Locale区域设置
        NSLocale* cn  = [NSLocale currentLocale];
        //获取NSDate在当前Locale下对应的字符串
        NSLog(@"%@", [date1 descriptionWithLocale:cn]);
        //获取两个日期之间较早的日期
        NSDate* earlier = [date1 earlierDate:date2];
        NSLog(@"较早的日期为:%@", earlier);
        //获取两个日期之间较晚的日期
        NSDate* later = [date1 laterDate:date2];
        NSLog(@"较晚的日期为:%@", later);
        //比较两个日期,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;
        }
        //获取两个时间之间的时间差
        //date1 - date3
        NSLog(@"date1与date3之间时间差%g秒"
              , [date1 timeIntervalSinceDate:date3]);
        //获取指定时间与现在的时间差
        //date2 - now
        NSLog(@"date2与现在时间差%g秒"
              , [date2 timeIntervalSinceNow]);

输出结果为:
2

创建NSDate的类方法与实例方法基本相似,但NSDate的类方法以date开头,而实例方法以init开头。两个NSDate之间可以比较大小,可以计算时间差,也可以把NSDate转化为复合当前NSLocale的格式字符串。

NSLocale:

NSLocale代表一个语言、国际环境,比如大陆的简体中文,就可以通过NSLocale对象来代表。同样一个日期,在不同的语言、国家环境下,显示出来的字符串是不同的。


7.2.2 日期格式器(NSDateFormatter)

NSDateFormatter代表一个日期格式器,它的功能就是完成NSDate与NSString之间的转换。

使用NSDateFormatter完成NSDate与NSString之间的转换的步骤如下:

1.创建一个NSDateFormatter对象。
2.调用NSDateFormatter的setDateStyle:、setTimeStyle:方法设置格式化日期、时间的风格。 其中,日期、时间风格支持如下几个枚举值。

NSDateFormatterNoStyle:不显示日期、时间的风格。
NSDateFormatterShortStyle:显示“短”的日期,时间风格
NSSDateFormatterMediumStyle:显示“中等”的日期、时间风格。
NSSDateFormatterLongStyle:显示“长”的日期、时间风格。
NSSDateFormatterFullStyle:显示“完整”的日期、时间风格。
如果打算使用自己的格式模版,调用NSDateFormatter的setDateFormate:方法设置日期、时间模版即可。

3.如果需要将NSDate转化为NSString,调用NSDateFormatter的stringFromDate:方法执行格式化即可;如果需要将NSString转化为NSDate,调用NSDateFormatter的dateFromString:方法执行格式化即可。

简单示范一下NSDateFormatter的功能和用法:
        //需要被格式化的时间
        //获取从1970年1月1日开始,20年之后的日期
        NSDate* dt = [NSDate dateWithTimeIntervalSince1970:
                      3600 * 24 * 366 * 20];
        //创建两个NSLocale,分别代表中国、美国
        NSLocale* locales[] = {
            [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]
            ,[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]
        };
        NSDateFormatter* df[8];
        //为上面两个NSLocale创建8个DateFormat对象
        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:dt]);
            NSLog(@"MEDIUM格式的日期格式:%@", [df[i * 4 + 1] stringFromDate:dt]);
            NSLog(@"LONG格式的日期格式:%@", [df[i * 4 + 2] stringFromDate:dt]);
            NSLog(@"FULL格式的日期格式:%@", [df[i * 4 + 3] 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);

输出结果为:
3

其中,日期格式化字符串(dateFormat)涉及的格式占位符

G  // AD,即公元
 
yy  // 显示年份的末尾两位
yyyy  // 显示完整年份
 
M  // 1-9月显示一位数字(1 ~ 9),10-12月显示两位数字(10 ~ 12)
MM  // 显示两位数组月份(01 ~ 12)
MMM  // 英文月份缩写
MMMM  // 英文月份全拼
 
d // 1-9日显示一位数字(1~9),10-31日显示两位数字(10~31)
dd  // 日期显示两位数字(01~31)
 
EEE  // 星期几缩写(例如星期二,英文是Tue,中文是周二)
EEEE  // 星期几全拼(例如星期二,英文是Tuesday,中文是星期二)
 
aa  // 加上这个,会显示AM/PM
 
H  // 24小时值,0-9小时显示一位数字(0~9),10-12小时显示两位数字(10~12)
HH  // 24小时制,显示两位数字
K  //  12小时制,0-9小时显示一位数字(0~9),10-12小时显示两位数字(10~12)
KK  //  12小时制,显示两位数字
 
m  // 0-9分显示一位数字(0~9),10-59分显示两位数字(10~59)
mm  // 显示两位数字(00~59)
 
s  // 0-9分显示一位数字(0~9),10-59分显示两位数字(10~59)
ss  // 分钟,显示两位数字(00~59)
S  // 显示毫秒


7.2.3 日历(NSCalendar)与日期组件(NSDateComponents)

为了能分开处理NSDate对象所包含的各个字段的数据,Foundation框架提供了NSCalendar对象,该对象包含如下两个常用方法:

  • (NSDateComponents*)components:fromDate: :从NSDate提取年、月、日、时、分、秒各时间段的信息。
  • dateFromComponents:(NSDateComponents*)comps :使用comps对象包含的年、月、时、分、秒各时间字段的信息来创建NSDate。
NSDateComponents

该对象专门用于封装年、月、日、时、分、秒各时间字段的信息。它只包含了对year、month、date、day、hour、minute、second、week、weekday等各字段的setter和getter方法。

从NSDate对象中分开获取各时间字段的数值的步骤如下:
  • 1.创建NSCalendar对象。
  • 2.调用NSCalendar的components:fromDate:方法获取NSDate对象中各时间字段的数值,该方法返回一个NSDateComponents对象。
  • 3.调用NSDateComponents对象的getter方法来获取各时间字段的数值。
使用各时间字段的数值来初始化NSDate对象的步骤如下:
  • 1.创建NSCalendar对象。
  • 2.创建一个NSDateComponents对象,调用该对象的setter方法来设置各时间字段的值。
  • 3.调用NSCalendar的dateFromComponents:(NSDateComponents*)初始化NSDate对象,该方法会返回一个NSDate对象。
 //获取代表公历的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 = 2013;
        comp2.month = 4;
        comp2.day = 12;
        comp2.hour = 15;
        comp2.minute = 34;
        //通过NSDateComponents所包含的时间字段的数值来恢复NSDateduixiang
        NSDate* date = [gregorian dateFromComponents:comp2];   
        NSLog(@"获取的日期为:%@", date);

输出结果为:
4


7.2.4 定时器(NSTimer)

使用定时器编程操作步骤:
  • 1.调用NSTimer的scheduledTimerWithTimeInterval:invocation:或scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:类方法来创建NSTimer对象。调用该类方法时,需要传入如下参数。

timeInterval:指定每隔多少秒执行一次任务。
invocation或target与selector:指定重复执行的任务。如果指定target和selector参数,则指定用某个对象的特定方法作为重复执行的任务;如果指定invocation参数,该参数需要传入一个NSInvocation对象,其中NSInvocation对象也是封装target和selector的,其实也是指定用某个对象的特定方法作为重复执行任务。
userInfo:该参数用于传入额外的附加信息。
repeats:该参数需要指定一个BOOL值,该参数控制是否需要重复执行任务。

  • 2.为第一步编写方法。
  • 3.销毁定时器。调用定时器的invalidate方法即可。

测试定时器:

@interface NSTimerTest : NSObject
@property (nonatomic, assign) int count;
- (void) start;
- (void) stop;
@end

@implementation NSTimerTest {
    NSTimer* timer;
}
@synthesize count;
- (void) start {
    timer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                     target:self  //指定以当前对象的info方法作为执行体
                                   selector:@selector(start)
                                   userInfo:nil
                                    repeats:YES];  //指定重复执行
    NSLog(@"正在执行第%d次任务", self.count++);
}

- (void) stop {
    NSLog(@"取消执行定时器");
    [timer invalidate];
}
@end

int main(int grac, char *grav[]) {
    @autoreleasepool {
        NSTimerTest* test = [[NSTimerTest alloc] init];
        for (int i = 0; i < 10; i++) {
            [test start];
        }
        [test stop];
    }
    return 0;
}

输出结果为:
6


7.3 对象复制

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


7.3.1 copy与mutableCopy方法

  • copy方法用于复制对象的副本。通常来说,copy方法总是返回对象的不可修改的副本,即使该对象本身是可修改的。

调用NSMutableString的copy方法,将会返回不可修改的字符串对象。

  • mutableCopy方法用于复制对象的可变副本。通常来说,mutableCopy方法总是返回该对象可修改的副本,即使被复制的对象本身是不可修改的,调用mutableCopy方法复制出来的副本也是可修改的。

程序调用NSString的mutableCopy方法,将会返回一个NSMutableString对象。

对复制对象的副本无论怎么修改,原对象都不会发生改变。

        NSMutableString* book = [NSMutableString
                                 stringWithString:@"疯狂iOS讲义"];
        //复制book字符串的可变副本
        NSMutableString* bookCopy = [book mutableCopy];
        //修改副本,对原字符串没有任何影响
        [bookCopy replaceCharactersInRange:NSMakeRange(2, 3)
                                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"];

输出结果为:
5


7.3.2 NSCopying与NSMutableCopy协议

虽然NSObject提供了copy和mutableCopy方法,但自定义类并不能直接调用这两个方法来复制自身

为了保证一个对象可以调用copy方法来复制自身的不可变副本,通常需要做如下事情:
  • 让该类实现NSCopying协议。
  • 让该类实现copyWithZone:方法。
为了保证一个对象可以调用mutableCopy方法来复制自身的可变副本,通常需要做如下事情:
  • 让该类实现NSMutableCopying协议。
  • 让该类实现mutableCopyWithZone:方法。
下面实现类的copy:
@interface FKDog : NSObject <NSCopying>
@property (nonatomic, strong) NSMutableString* name;
@property (nonatomic, assign) int age;
@end

@implementation FKDog
@synthesize name;
@synthesize age;
- (id) copyWithZone:(NSZone*) zone {
    NSLog(@"--执行copyWithZone--");
    FKDog* dog = [[[self class] allocWithZone:zone] init];
    dog.name = self.name;
    dog.age = self.age;
    return dog;
}
@end

int main(int grac, char *grav[]) {
    @autoreleasepool {
        FKDog* dog1 = [[FKDog alloc] init];
        dog1.name = [NSMutableString stringWithString:@"旺财"];
        dog1.age = 20;
        FKDog* dog2 = [dog1 copy];
        dog2.name = [NSMutableString stringWithString:@"snoopy"];
        dog2.age = 12;
        NSLog(@"dog1的名字为:%@", dog1.name);
        NSLog(@"dog1的年龄为:%d", dog1.age);
        NSLog(@"dog2的名字为:%@", dog2.name);
        NSLog(@"dog2的年龄为:%d", dog2.age);
        
    }
    return 0;
}

协议系统自带!

输出结果为:
66

  • 当程序调用上述类的copy方法来复制自身时,底层实际上调用了copyWithZone:方法来执行实际的复制操作。因为此处的类没有提供对应的不可变类,自然也就无法复制不可变的该类的对象。如果程序为该类提供了不可变类,当然还是应该让该类的copyWithZone:返回不可变的该类的对象。
  • 如果重写copyWithZone:方法时,其父类已经实现NSCopying协议,并重写过copyWithZone:方法,那么子类重写copyWithZone:方法应先调用父类的copy方法复制从父类继承得到的成员变量,然后对子类定义的成员变量进行赋值。
假如父类已经重写copyWithZone:方法,那么子类重写copyWithZone:方法的格式如下:
- (void) copyWithZone: (NSZone*) zone {
   id obj = [super copy];
   //对子类定义的成员变量进行赋值。
   ...
   return obj;
}

7.3.3 浅复制与深复制

浅复制(shallow copy)

当对象的实例变量时指针变量时,如果程序只是复制该指针的地址,而不是真正复制指针所指向的对象,这种方式就被称为“浅复制”。

浅复制出来的两个对象是两个指针变量,他们指向的是同一个地址。
676

深复制(deep copy)

深复制不仅会复制对象本身,而且会“递归”复制每个指针类型的实例变量,直到两个对象没有任何公共的部分。
将上述的copyWithZone:改为深复制:

- (id) copyWithZone: (NSZone*) zone {
    NSLog(@"--执行copyWithZone--");
    FKDog* dog = [[[self class] allocWithZone:zone] init];
    dog.name = [self.name mutableCopy];
    dog.age = self.age;
    return dog;
}

上面程序中并没有简单地将被复制对象的name实例变量的值赋给新对象的name实例变量,而是先将原对象name实例变量复制了一份可变副本,再将该可变副本的值赋给新对象的name实例变量。这样就保证了原对象和新对象没有任何公共部分,这就实现了深复制


7.3.4 setter方法的复制选项

前面介绍合成setter和getter方法时提到可以使用copy指示符,copy指示符就是指定当程序调用setter方法复制时,实际上是将传入参数的副本赋给程序的实例变量。
定义合成getter、setter方法时并没有提供mutableCopy指示符,只有copy指示符。

系统默认的setter方法如下:

例如setName:

- (void) setName: (NSMutableString*) aname {
   name = [aname copy];
}

copy方法默认是复制该对象的不可变副本,虽然程序传入的NSMutableString,但程序调用该参数的copy方法得到的是不可变副本。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值