I previously added the code on p.292 (copy prevents changing lastName) to main.m. It worked as expected(logging myObj shows “Ono”, not “OnoLennon”). I then tried the code on p 298 (use key-value coding), then had to modify the accessors back to using _productName = [pn copy], instead of [self setProductName:pn]; (mentioned on p.285), built and ran, and the code from p.292 logs “OnoLennon: 120 volts”.
So it appears KV coding doesn’t copy, but sets a pointer to the new object when you [x appendString:myObj]. Very interesting, or I’m thinking about this wrong. My code is below.
BNRAppliance.h
@interface BNRAppliance : NSObject
//ch35 need for KV coding
{
NSString *_productName;
}
//comment next line to use KV coding
//@property (nonatomic, copy)NSString *productName;
@property (nonatomic) int voltage;
//the designated initializer
-(instancetype)initWithProductName:(NSString *)pn;
@end
BNRAppliance.m
#import “BNRAppliance.h”
@implementation BNRAppliance
-(instancetype)init {
return [self initWithProductName:@“Unknown”];
}
-(instancetype)initWithProductName:(NSString *)pn {
//call NSObject’s init method
self = [super init];
//did it return something non-nil?
if (self){
//set the product name
_productName = [pn copy];
//[self setProductName:pn];
//give voltage a starting value
_voltage = 120;
//[self setVoltage:120];
}
//return a pointer to the new object
return self;
}
-(NSString )description{
return [NSString stringWithFormat:@"<%@: %d volts>", _productName, self.voltage];
}
/
-(void)setVoltage:(int)voltage {
NSLog(@“setting voltage to %d”, voltage);
_voltage = voltage;
}
*/
@end
main.m
int main(int argc, const char * argv[]) {
@autoreleasepool {
BNRAppliance *a = [[BNRAppliance alloc] init];
NSLog(@“a is %@”, a);
//[a setProductName:@“Washing Machine”];
//for key-value coding
[a setValue:@“Washing Machine1” forKey:@“productName”];
//[a setVoltage:240];
[a setValue:[NSNumber numberWithInt:240] forKey:@“voltage”];
NSLog(@“a is %@”, a);
NSLog(@"the product name is %@", [a valueForKey:@"productName"]);
//ch34 on properties
NSMutableString *x = [[NSMutableString alloc] initWithString:@"Ono"];
BNRAppliance *myObj = [[BNRAppliance alloc] init];
//[myObj setProductName:x];
[myObj setValue:x forKey:@"productName"];
//if you use key-value coding, you don't copy, so you can append the productName in myObj
[x appendString:@"Lennon"];
NSLog(@"%@", myObj);
}
return 0;
}