作为一个刚接触Objective-C的人谁能给我一个关于retain, assign, copy和其他我没有注意到的@property指令的概述?他们在做什么,为什么我要用一个而不是另一个?


由MrMage链接的文章不再工作。所以,以下是我在Objective-C中(非常)短时间编程中学到的东西:

非原子与原子 -“atomic”为默认值。总是使用“nonatomic”。我不知道为什么,但我读过的书说“很少有理由”使用“atomic”。(顺便说一句:我读的书是BNR的“iOS编程”书。)

Readwrite和readonly —默认为readwrite。当你@synthesize时,会为你创建一个getter和一个setter。如果使用"readonly",则不会创建setter。将它用于对象实例化后不希望更改的值。

保留,复制,分配

"assign" is the default. In the setter that is created by @synthesize, the value will simply be assigned to the attribute. My understanding is that "assign" should be used for non-pointer attributes. "retain" is needed when the attribute is a pointer to an object. The setter generated by @synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it. "copy" is needed when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.


原子属性一次只能被一个线程访问。它是线程安全的。默认是atomic .请注意没有关键字atomic

非原子的意思是多个线程可以访问这个项目。它是线程不安全的

因此,在使用原子的.时应该非常小心,因为它会影响代码的性能


在阅读了许多文章后,我决定将所有属性信息放在一起:

原子 // 默认的 原子 强=保留/ /违约 弱= unsafe_unretained 保留 分配 // 默认的 unsafe_unretained 复制 只读的 读写 // 默认的

下面是详细文章的链接,您可以在其中找到这些属性。

非常感谢所有在这里给出最好答案的人!!

iOS中的可变属性属性或修饰符

下面是文章中的示例描述

原子 -Atomic表示只有一个线程访问该变量(静态类型)。 -Atomic线程安全。 但它的性能较慢 -atomic是默认行为 -非垃圾收集环境中的原子访问器(即当使用retain/release/autorelease时)将使用一个锁来 确保另一个线程不会干扰值的正确设置/获取。 -它实际上不是一个关键字。

例子:

@property (retain) NSString *name;

@synthesize name;

原子 -Nonatomic表示多个线程访问变量(动态类型)。 nonatomic是线程不安全的。 但它的性能很快 -Nonatomic不是默认行为,我们需要在属性属性中添加nonatomic关键字。 当两个不同的进程(线程)同时访问同一个变量时,可能会导致意想不到的行为。

例子:

@property (nonatomic, retain) NSString *name;

@synthesize name;

解释:

Suppose there is an atomic string property called "name", and if you call [self setName:@"A"] from thread A, call [self setName:@"B"] from thread B, and call [self name] from thread C, then all operation on different thread will be performed serially which means if one thread is executing setter or getter, then other threads will wait. This makes property "name" read/write safe but if another thread D calls [name release] simultaneously then this operation might produce a crash because there is no setter/getter call involved here. Which means an object is read/write safe (ATOMIC) but not thread safe as another threads can simultaneously send any type of messages to the object. Developer should ensure thread safety for such objects.

如果属性“name”是非原子的,那么上面例子中的所有线程——A、B、C和D将同时执行,产生任何不可预测的结果。在原子的情况下,A, B或C中的任何一个将首先执行,但D仍然可以并行执行。

strong (iOS4 = retain ) -it says "keep this in the heap until I don't point to it anymore" -in other words " I'am the owner, you cannot dealloc this before aim fine with that same as retain" -You use strong only if you need to retain the object. -By default all instance variables and local variables are strong pointers. -We generally use strong for UIViewControllers (UI item's parents) -strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.

例子:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

weak (iOS4 = unsafe_unretained ) -it says "keep this as long as someone else points to it strongly" -the same thing as assign, no retain or release -A "weak" reference is a reference that you do not retain. -We generally use weak for IBOutlets (UIViewController's Childs).This works because the child object only needs to exist as long as the parent object does. -a weak reference is a reference that does not protect the referenced object from collection by a garbage collector. -Weak is essentially assign, a unretained property. Except the when the object is deallocated the weak pointer is automatically set to nil

例子:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

强与弱的解释,感谢BJ Homer:

Imagine our object is a dog, and that the dog wants to run away (be deallocated). Strong pointers are like a leash on the dog. As long as you have the leash attached to the dog, the dog will not run away. If five people attach their leash to one dog, (five strong pointers to one object), then the dog will not run away until all five leashes are detached. Weak pointers, on the other hand, are like little kids pointing at the dog and saying "Look! A dog!" As long as the dog is still on the leash, the little kids can still see the dog, and they'll still point to it. As soon as all the leashes are detached, though, the dog runs away no matter how many little kids are pointing to it. As soon as the last strong pointer (leash) no longer points to an object, the object will be deallocated, and all weak pointers will be zeroed out. When we use weak? The only time you would want to use weak, is if you wanted to avoid retain cycles (e.g. the parent retains the child and the child retains the parent so neither is ever released).

保留=强大 -它被保留,旧的值被释放并被分配 -retain指定在赋值时发送新值-retain,旧值发送-release -retain和strong是一样的。 -苹果说如果你写retain,它会自动转换/像strong一样工作。 -像“alloc”这样的方法包含一个隐式的“retain”

例子:

@property (nonatomic, retain) NSString *name;

@synthesize name;

分配 -assign是默认值,只执行变量赋值 -assign是一个属性属性,告诉编译器如何合成属性的setter实现 -I将对C基元属性使用assign,对Objective-C对象的弱引用使用weak。

例子:

@property (nonatomic, assign) NSString *address;

@synthesize address;

unsafe_unretained -unsafe_unretained是一个所有权限定符,告诉ARC如何插入保留/释放调用 -unsafe_unretained是assign的ARC版本。

例子:

@property (nonatomic, unsafe_unretained) NSString *nickName;

@synthesize nickName;

copy -copy is required when the object is mutable. -copy specifies the new value should be sent -copy on assignment and the old value sent -release. -copy is like retain returns an object which you must explicitly release (e.g., in dealloc) in non-garbage collected environments. -if you use copy then you still need to release that in dealloc. -Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.

例子:

@property (nonatomic, copy) NSArray *myArray;

@synthesize myArray;

在了解@property的属性之前,您应该知道@property的用途。

@property offers a way to define the information that a class is intended to encapsulate. If you declare an object/variable using @property, then that object/variable will be accessible to other classes importing its class. If you declare an object using @property in the header file, then you have to synthesize it using @synthesize in the implementation file. This makes the object KVC compliant. By default, compiler will synthesize accessor methods for this object. accessor methods are : setter and getter.

例子: . h

@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end

.m

@implementation XYZClass
@synthesize name;
@end

现在编译器将为name合成访问器方法。

XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method

@property的属性列表 原子,非原子,保留,复制,只读,读写,赋值,强,getter=方法,setter=方法,unsafe_unretained Atomic是默认行为。如果一个对象被声明为原子的,那么它就变成线程安全的。线程安全的意思是,在同一时间,该类的特定实例中只有一个线程可以控制该对象。

如果线程正在执行getter方法,那么其他线程不能对该对象执行setter方法。它很慢。

@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`

Nonatomic不是线程安全的。可以使用nonatomic property属性指定合成访问器只是直接设置或返回一个值,而不保证从不同线程同时访问相同的值会发生什么。

因此,访问非原子属性要比访问原子属性快。

@property (nonatomic)NSString *name;   

当属性是指向对象的指针时,需要Retain。

setter方法将增加对象的保留计数,因此它将占用自动释放池中的内存。

@property (retain)NSString *name;

如果你用copy,你不能用retain。使用类的复制实例将包含其自己的副本。

即使一个可变字符串被设置并随后被更改,实例也会捕获它在设置时拥有的任何值。不会合成setter和getter方法。

@property (copy) NSString *name;

now,

NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];    
xyzObj.name = nameString;    
[nameString appendString:@"Pizza"]; 

名称不受影响。

如果你不想让属性通过setter方法被改变,你可以声明属性。

编译器将生成一个getter,而不是setter。

@property (readonly) NSString *name;

读写是默认行为。不需要显式地指定readwrite属性。

它是只读的反义词。

@property (readwrite) NSString *name;

Assign将生成一个setter,它将值直接赋给实例变量,而不是复制或保留它。这对于像NSInteger和CGFloat这样的基本类型,或者你不直接拥有的对象,比如委托,是最好的。

请记住,当启用垃圾收集时,retain和assign基本上是可互换的。

@property (assign) NSInteger year;

坚强是保留的替代品。

它带有ARC。

@property (nonatomic, strong) AVPlayer *player; 

如果您想为getter方法使用不同的名称,可以通过向属性中添加属性来指定自定义名称。

对于布尔属性(具有YES或NO值的属性),getter方法通常以单词“is”开头。

@property (getter=isFinished) BOOL finished;

如果您想为setter方法使用不同的名称,可以通过向属性中添加属性来指定自定义名称。

方法应该以冒号结束。

@property(setter = boolBool:) BOOL finished;

在Cocoa和Cocoa Touch中有一些类还不支持弱引用,这意味着你不能声明一个弱属性或弱局部变量来跟踪它们。这些类包括NSTextView, NSFont和NSColorSpace等。如果需要使用对这些类之一的弱引用,则必须使用不安全引用。

不安全引用类似于弱引用,因为它不保持其相关对象的活动状态,但如果目标对象被释放,它不会被设置为nil。

@property (unsafe_unretained) NSObject *unsafeProperty;

如果你需要指定多个属性,只需将它们包含为逗号分隔的列表,如下所示:

@property (readonly, getter=isFinished) BOOL finished;

喜欢这个关于objective-c在iOS中的属性的链接…

https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html