我对 iOS 开发和 Objective-C 编程非常陌生。我一直在应用程序开发库上做练习。
这是我正在尝试理解的当前练习。
3. 测试如果您将可变字符串设置为该人的名字,然后在调用修改后的 sayHello 方法之前更改该字符串,会发生什么情况。通过添加复制属性来更改 NSString 属性声明并再次测试。
然而,我尝试这样做,尽管使用了复制属性,但我修改的 NSString 实际上确实发生了变化。
这是我的声明和实现以及我的测试代码。
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]));
}
}
考虑这个较短的示例(运行在代码运行者 https://itunes.apple.com/us/app/coderunner/id433335799 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)