ios – 使用“copy”属性属性来维护不可变的NSString

前端之家收集整理的这篇文章主要介绍了ios – 使用“copy”属性属性来维护不可变的NSString前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是Objective-C中iOS开发和编程的新手.我一直在app dev库上做练习.

这是我想要了解的当前练习.
3.测试如果将可变字符串设置为该人的名字会发生什么,然后在调用修改后的sayHello方法之前改变该字符串.通过添加copy属性更改NSString属性声明并再次测试.

我尝试这样做,但是我修改的NSString实际上改变了,尽管使用了copy属性.

这是我的声明和实现以及我的测试代码.

XYZPerson.h
#import <Foundation/Foundation.h>

@interface XYZPerson : NSObject

@property (copy) NSString *firstName;
@property NSString *lastName;
@property NSDate *dob;

- (void)sayHello;
- (void)saySomething:(NSString *)greeting;

+ (id)init;
+ (id)personWithFirstName:(NSString *)firstName lastName:(NSString *)lastName dob:(NSDate   *)dateOfBirth;


@end

//XYZPerson.m
#import "XYZPerson.h"

@implementation XYZPerson

@synthesize firstName = _firstName;
@synthesize lastName = _lastName;
@synthesize dob = _dob;


- (void)sayHello {
    [self saySomething:@"Hello World!"];
    NSLog(@"This is %@ %@",self.firstName,self.lastName);
}

- (void)saySomething:(NSString *)greeting {
    NSLog(@"%@",greeting);
}

+ (id)init {
    return [self personWithFirstName:@"Yorick" lastName:@"Robinson" dob:8/23/1990];
}

+ (id)personWithFirstName:(NSString *)firstName lastName:(NSString *)lastName dob:(NSDate   *)dateOfBirth{
    XYZPerson *person = [[self alloc] init];
    person.firstName = firstName;
    person.lastName = lastName;
    person.dob = dateOfBirth;

    return person;
}

@end

//Test code
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "XYZPerson.h"
#import "XYZShoutingPerson.h"


int main(int argc,char *argv[])
{
    @autoreleasepool {
        XYZPerson *guy = [XYZPerson init];
        [guy sayHello];

        //I thought that this change would never be made,but it is everytime I run the code.
        guy.firstName = @"Darryl";
        [guy sayHello];

        XYZShoutingPerson *girl = [XYZShoutingPerson init];
        [girl sayHello];
        return UIApplicationMain(argc,argv,nil,NSStringFromClass([AppDelegate class]));
    }
}

解决方法

考虑这个较短的例子(运行在 CodeRunner btw):
#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic,strong) NSString *name; // strong should be copy
@end

@implementation Person
@end

int main(int argc,char *argv[]) {
    @autoreleasepool {
        Person *p = [Person new];

        NSMutableString *name = [[NSMutableString alloc] initWithString:@"Alice"];
        p.name = name;
        NSLog(@"%@",p.name); // prints Alice

        [name appendString:@"xxx"];
        NSLog(@"%@",p.name); // prints Alicexxx
    }
}

我将名称指向一个可变字符串,然后附加一些字符.结果,名称在对象内部发生了变化.但是,如果在声明属性时将strong替换为copy,则将仅为Person对象创建新的不可变字符串.

故事的寓意是,当有人传递一个物体然后该物体发生变化时,使用副本可以防止副作用.

消息 – [NSString copy]在传递可变字符串(NSMutableString)时生成副本,或者在不可变(NSString)时保留.因此,在声明NSString属性时始终复制:

@property (nonatomic,copy)   NSString *string;  // OK
@property (nonatomic,strong) NSString *string;  // strong should be copy

猜你在找的iOS相关文章