2
votes

I have four variations of the same class.

A mix of pointer, non-pointer, assign vs copy.

What are the implications of using each case?

1)

@interface fruit:NSObject{
NSString apple;
}
@property(nonatomic, retain);
@end

2)

@interface fruit:NSObject{
NSString apple;
}
@property(nonatomic, assign);
@end

3)

@interface fruit:NSObject{
NSString *apple;
}
@property(nonatomic, retain);
@end

4)

@interface fruit:NSObject{
NSString *apple;
}
@property(nonatomic, assign);
@end
2
another option to consider is (nonatomic, copy), which will (obviously) copy the string instead of retaining or assigning it. - Dave DeLong

2 Answers

9
votes

1)

@interface fruit:NSObject{
NSString apple;
}
@property(nonatomic, retain);
@end

You cannot allocate NSObjects on the stack or as object instance variables. In its early days, Objective-C did allow this, but it doesn't anymore. This code is incorrect.

2)

@interface fruit:NSObject{
NSString apple;
}
@property(nonatomic, assign);
@end

You cannot allocate NSObjects on the stack or as object instance variables. In its early days, Objective-C did allow this, but it doesn't anymore. This code is incorrect.

3)

@interface fruit:NSObject{
NSString *apple;
}
@property(nonatomic, retain);
@end

You are retaining an ownership stake in the NSString instance, guaranteeing that it will not be deallocate while you retain that ownership. Since NSMutableString is a subclass of NSString, you may have been given a mutable string at assignment, so other code may modify the string's value without your knowledge (unless you are using Key-Value Observing to observe those changes). For this reason, it is usually appropriate to use copy semantics for properties that you intend to hold an immutable value (NSString, NSData, NSArray, NSSet are the common--though not exaustive--suspects).

4)

@interface fruit:NSObject{
NSString *apple;
}
@property(nonatomic, assign);
@end

You are not retaining an ownership interest in the string, meaning that it may be deallocated without your knowlege. In reference-counting environments, this is the standard practice for delegate properties, since retaining them would likely create a retain cycle. The code that is responsible for deallocating the string must set your apple property to nil before doing so (in a ref-counted environment). In a GC environment, your assignment will keep the string alive if you have a __strong pointer or give you a zeroing (set to 0 at dealloc) if you have a __weak pointer in your declaration.

2
votes

To my knowledge you should always use either retain or copy with an NSString*. Assign on a pointer (4) will not increment the reference count, so will leak memory or rather it would mean you end up accessing released memory as the count would prematurely reach 0.

I don't know if you can use NSString as a native type. I always use it as a pointer.