2010-02-12 91 views

回答

257

MrMage链接的文章不再有效。所以,下面是我在Objective-C中短时间内学到的知识:

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

readwrite与只读 - “readwrite”是默认值。当你@synthesize时,你会为你创建一个getter和一个setter。如果您使用“只读”,则不会创建setter。在实例化对象后,将它用作您不想更改的值。

保留与副本与分配

  • “分配” 是默认的。在由@synthesize创建的setter中,该值将被简单地分配给该属性。我的理解是,“分配”应该用于非指针属性。
  • 当属性是指向对象的指针时,需要“保留”。 @synthesize生成的setter将保留(也就是添加一个保留计数)该对象。完成后您需要释放对象。
  • 当对象可变时需要“复制”。如果此时需要此对象的值,请使用此选项,并且您不希望该值反映该对象的其他所有者所做的任何更改。由于您保留了副本,因此在完成对象时需要释放该对象。
+0

@Blamdarot - 我需要与ARC释放以及 – Dejell 2012-12-27 15:48:15

+9

@Odelya - 不,如果你在使用ARC时释放,我相信你会得到一个编译器错误。 – Blamdarot 2012-12-28 19:22:53

+41

“总是使用非原子”是不好的建议。你应该知道当你使用非原子时你放弃了什么。 – 2013-10-24 01:42:24

7

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

非原子意味着多个线程可以访问该项目。它是线程不安全

所以在使用原子一个应该非常小心。因为它会影响您的代码

+2

“注意:属性原子性与对象的线程安全性不是同义的。”从https://developer.apple。com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#// apple_ref/doc/uid/TP40011210-CH5-SW4 – jk7 2015-12-16 01:40:31

132

的性能阅读多篇文章后,我决定一起把所有的属性信息:

  1. 原子//默认
  2. 非原子
  3. 强=保留// default
  4. weak = unsafe_unretained
  5. retain
  6. 分配//默认
  7. unsafe_unretained
  8. 副本
  9. 只读
  10. 读写//默认

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

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

Variable property attributes or Modifiers in iOS

这里是从第样本描述

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

实施例:

@property (retain) NSString *name; 

@synthesize name; 
  • 非原子 -Nonatomic意味着多线程访问的变量(动态型)。 - 单体是线程不安全的。 - 但它在性能上很快 - 不是默认行为,我们需要在属性属性中添加非原子关键字。 - 当两个不同的进程(线程)同时访问同一个变量时,可能会导致意外行为。
  • 例子:

    @property (nonatomic, retain) NSString *name; 
    
    @synthesize name; 
    

    解释:

    假设有一个名为 “名” 原子串属性,如果你调用[自我的setName:@ “A”]从线程A, 从线程B调用[self setName:@“B”],并从线程C调用[self name],然后所有在不同线程上的操作都将被串行执行,这意味着如果一个线程正在执行setter或getter,则其他线程将等待。这使属性“名称”可读/写安全,但如果另一个线程D同时调用[名称释放],则此操作可能会导致崩溃,因为此处不涉及setter/getter调用。这意味着一个对象是可读/写安全的(ATOMIC),但不是线程安全的,因为另一个线程可以同时向对象发送任何类型的消息。开发人员应确保此类对象的线程安全。

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

  • (iOS4的保留=) - 它表示“记住这堆直到我不指向它了” - 换句话说“我'所有者,您不能在与保留相同的目标前重新分配“ - 只有在需要保留该对象时才能使用强壮。 - 默认情况下,所有实例变量和局部变量都是强指针。 -我们通常对UIViewControllers(UI项目的父母)使用较强 -strong与ARC一起使用,它基本上可以帮助您,无需担心对象的保留数。 ARC完成后会自动为您发布。使用关键字strong意味着您拥有该对象。
  • 实施例:

    @property (strong, nonatomic) ViewController *viewController; 
    
    @synthesize viewController; 
    
  • (iOS4的= unsafe_unretained) - 它表示 “只要别人点强烈保留此将其” - 与分配,保留或发布一样 - “弱”引用是您不保留的引用。 -我们通常对IBOutlets(UIViewController的Childs)使用weak。这是可行的,因为只要父对象具有子对象 就需要存在。 弱引用是一个引用,它不保护引用的对象不被垃圾收集器收集。 -弱者本质上是一种不再保留的财产。除了当对象被释放弱指针会自动设置为无
  • 例子:

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

    强&弱说明,Thanks to BJ Homer

    想象我们的对象是狗,并且狗想逃跑(被释放)。 强壮的指针就像狗上的皮带。只要你有狗附着的皮带,狗就不会逃跑。如果五个人把一条狗绑在一条狗上,(五个指向一个物体的强指针),那么只有当所有五条皮带分开时,狗才不会跑掉。 另一方面,弱指针就像小孩子指着狗说,“看!一只狗!”只要狗还在皮带上,小孩们仍然可以看到狗,他们仍然会指向它。不过,只要所有的皮带都脱落,无论有多少小孩指着它,狗都会跑掉。 只要最后一个强指针(皮带)不再指向一个对象,该对象就会被释放,所有弱指针将被清零。 当我们使用弱? 唯一一次你想使用弱,是如果你想避免保留周期 (例如,父母保留孩子,孩子保留父母,所以永远不会被释放)。

  • 保留 =强 -it被保留,旧值被释放,它被分配 -retain指定新值应该在分配和旧值被发送-retain发送-release -retain是一样强。苹果说,如果你写保留它会自动转换/工作只有强壮。 - 方法如 “黄金” 包括隐含的 “保留”
  • 实施例:

    @property (nonatomic, retain) NSString *name; 
    
    @synthesize name; 
    
  • 分配 -assign是默认设置,简单地进行变量赋值 -assign是一个属性属性,告诉编译器如何综合属性的setter实现 -I将使用C语言属性的赋值,而弱赋值给Objective-C对象。
  • 实施例:

    @property (nonatomic, assign) NSString *address; 
    
    @synthesize address; 
    
  • unsafe_unretained

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

  • 实施例:

    @property (nonatomic, unsafe_unretained) NSString *nickName; 
    
    @synthesize nickName; 
    
  • 拷贝当对象是可变 -copy是必需的。 -copy指定应发送的新值-copy赋值和旧值发送-release。 -copy就像保留返回一个对象,你必须在非垃圾收集环境中明确释放(例如,在dealloc中)。 如果您使用副本,那么您仍然需要在dealloc中释放该副本。 - 如果此时需要此对象的值,请使用此选项,并且您不希望该值反映该对象的其他 所有者所做的任何更改。由于您保留了副本,因此在完成对象时需要释放该对象。
  • 例子:

    @property (nonatomic, copy) NSArray *myArray; 
    
    @synthesize myArray; 
    
    +2

    我认为,在弧之后,不再使用保留。 – mert 2014-12-08 10:03:37

    +1

    完整列表未命中2个选项:setter和getter,这也是唯一需要参数的选项。 – 2015-08-06 05:24:34

    265

    你知道@属性的属性之前,您应该知道什么是使用@属性的。

    • @property提供了一个方法来定义一个类被用于封装的信息。 如果您使用@property声明对象/变量,那么该对象/变量将可被导入其类的其他类访问。

    • 如果声明在头文件使用@property一个对象,那么你必须在实现文件中使用@synthesize合成它。这使得对象KVC兼容。默认情况下,编译器将为该对象合成访问器方法

    • 存取方法是:setter和getter。

    例子: .H

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

    .M

    @implementation XYZClass 
    @synthesize name; 
    @end 
    

    现在,编译器将综合存取方法

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

      原子,非原子,保留,复制,只读,读写,分配,强,吸气剂=方法,设置器方法=属性列表,unsafe_unretained

    • 原子是默认行为。如果一个对象被声明为原子,那么它就变成了线程安全的。线程安全的手段,一次只有该类的特定实例的一个线程可以控制该对象。

    如果线程正在执行getter方法,则其他线程无法对该对象执行setter方法。它很慢。

    @property NSString *name; //by default atomic` 
    @property (atomic)NSString *name; // explicitly declared atomic` 
    
    • 非原子不是线程安全的。您可以使用nonatomic属性来指定合成访问器直接设置或返回值,但不保证如果从不同线程同时访问相同的值会发生什么情况。

    由于这个原因,访问非原子性质比原子性质快。

    @property (nonatomic)NSString *name; 
    
    • 保留当属性是一个指向对象是必需的。

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

    @property (retain)NSString *name; 
    
    • 副本如果使用复制,则不能使用保留。使用该类的副本实例将包含其自己的副本。

    即使设置了可变字符串并随后更改,实例也会捕获它在设置时的值。将不会合成setter和getter方法。

    @property (copy) NSString *name; 
    

    现在,

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

    将不受影响。

    • 只读如果您不希望允许通过setter方法要更改的属性,可以只读申报财产。

    编译器将生成一个getter,但不会生成setter。

    @property (readonly) NSString *name; 
    
    • 读写是默认行为。您不需要明确指定readwrite属性。

    它只是只读的对面。

    @property (readwrite) NSString *name; 
    
    • 分配将产生的值的实例变量直接分配,而不是复制或保持它的装定。这对于像NSInteger和CGFloat这样的原始类型或者不直接拥有的对象(例如委托)来说是最好的。

    请记住,启用垃圾回收时保留和赋值基本上是可以互换的。

    @property (assign) NSInteger year; 
    
    • 是保留的替代品。

    它带有ARC。

    @property (nonatomic, strong) AVPlayer *player; 
    
    • 的getter方法=如果要使用不同的名称为getter方法,它可以通过添加属性的属性来指定自定义名称。

    在布尔属性(属性具有一个YES或NO的值)的情况下,它是常用于吸气剂的方法,以与所述字起始“是”

    @property (getter=isFinished) BOOL finished; 
    
    • 的setter =方法如果要为setter方法使用不同的名称,可以通过向属性添加属性来指定自定义名称。

    该方法应该以冒号结尾。

    @property(setter = boolBool:) BOOL finished; 
    
    • unsafe_unretained有可可和可可触摸几类,还不支持弱引用,这意味着你不能声明弱属性或弱的局部变量来跟踪它们, 。这些类包括NSTextView,NSFont和NSColorSpace等。如果您需要对这些类中的某个类使用弱引用,则必须使用不安全的引用。

    不安全参考类似于它不保持其相关对象活着弱引用,但是如果目标对象被释放它不会被设置为

    @property (unsafe_unretained) NSObject *unsafeProperty; 
    

    如果需要指定多个属性,只需把它们作为一个逗号分隔的列表,像这样:

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

    此外,弱意味着没有对该对象引用的引用计数,但它完全被引用或根本没有引用。有点像“是的,引用了我的东西”与“对我的引用存在”(这就是强烈的东西)。 – 2013-08-16 19:35:15

    +5

    忽略关于垃圾收集的答案中的一行,因为垃圾收集在Mac OS X中已弃用,并且每个[Apple文档]的iOS中都不存在(https://developer.apple.com/library/mac/releasenotes/ObjectiveC/ RN-TransitioningToARC /介绍/ Introduction.html#// apple_ref/DOC/UID/TP40011226-CH1-SW17)。 – 2013-10-24 01:41:43

    +0

    每次我读了一些关于obj-c属性指令的信息时,我都很困惑!我需要知道它背后的计算机科学。任何人都可以将我链接到适当的文献吗? – AceN 2015-05-26 12:04:21

    相关问题