Objective-C 101 (retain vs assign) NSString

感情迁移 提交于 2019-12-28 01:43:06

问题


A 101 question

Let's say i'm making database of cars and each car object is defined as:

#import <UIKit/UIKit.h>

@interface Car:NSObject{
    NSString *name;
}

@property(nonatomic, retain) NSString *name;

Why is it @property(nonatomic, retain) NSString *name; and not @property(nonatomic, assign) NSString *name;?

I understand that assign will not increment the reference counter as retain will do. But why use retain, since name is a member of the todo object the scope of it is to itself.

No other external function will modify it either.


回答1:


There's no such thing as the "scope of an object" in Objective-C. Scope rules have nothing to do with an object's lifetime — the retain count is everything.

You usually need to claim ownership of your instance variables. See the Objective-C memory management rules. With a retain property, your property setter claims ownership of the new value and relinquishes ownership of the old one. With an assign property, the surrounding code has to do this, which is just as mess in terms of responsibilities and separation of concerns. The reason you would use an assign property is in a case where you can't retain the value (such as non-object types like BOOL or NSRect) or when retaining it would cause unwanted side effects.

Incidentally, in the case of an NSString, the correct kind of property is usually copy. That way it can't change out from under you if somebody passes in an NSMutableString (which is valid — it is a kind of NSString).




回答2:


and don't forget to access it via

self.name = something;

because

name = something;

will not care about the generated setter/getter methods but instead assign the value directly.




回答3:


Without retain there is no guarantee the NSString* you are setting name with will live any longer than the assignment statement itself. By using the retain property for the synthesized setter you're allowing it to tell the memory management system that there is at least one more object interested in keeping the NSString* around.




回答4:


For those who are looking for it, Apple's documentation on property attributes is here.




回答5:


The self. in:

self.name = something;

is important! Without it, you are accessing the variable directly and bypassing the setter.

The older style (correct me if I am wrong) would have been:

[self setName:something];

Anyway, this notation was the (vaguely familiar sounding) advice that I really needed when I went looking for proper @properties on NSStrings. Thanks Axel.




回答6:


After reading so many Articles, SO posts and made demo apps to check Variable property attributes, I decided to put all the attributes information together

  1. atomic //default
  2. nonatomic
  3. strong=retain //default
  4. weak= unsafe_unretained
  5. retain
  6. assign //default
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite //default

so below is the detailed article link where you can find above mentioned all attributes, that will defiantly help you. Many thanks to all the people who give best answers here!!

Variable property attributes or Modifiers in iOS

  1. retain = strong
    • it is retained, old value is released and it is assigned
    • retain specifies the new value should be sent -retain on assignment and the old value sent -release
    • retain is the same as strong.
    • apple says if you write retain it will auto converted/work like strong only.
    • methods like "alloc" include an implicit "retain"

Example:

@property (nonatomic, retain) NSString *name;

@synthesize name;
  1. assign
    • assign is the default and simply performs a variable assignment
    • assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
    • I would use assign for C primitive properties and weak for weak references to Objective-C objects.

Example:

@property (nonatomic, assign) NSString *address;

@synthesize address;



回答7:


Google's Objective-C Style Guide covers this pretty well:

Setters taking an NSString, should always copy the string it accepts. Never just retain the string. This avoids the caller changing it under you without your knowledge. Don't assume that because you're accepting an NSString that it's not actually an NSMutableString.




回答8:


Would it be unfortunate if your class got this string object and it then disappeared out from under it? You know, like the second time your class mentions that object, it's been dealloc'ed by another object?

That's why you want to use the retain setter semantics.



来源:https://stackoverflow.com/questions/1380338/objective-c-101-retain-vs-assign-nsstring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!