@property在Objective-C中保留,赋值,复制,非原子

时间:2010-02-12 23:51:26

标签: ios objective-c iphone memory-management

作为Objective-C的新手,有人可以按照@property指令给我概述保留,分配,复制和其他任何我缺失的内容吗?他们在做什么,为什么我要用另一个呢?

5 个答案:

答案 0 :(得分:286)

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

  • @property 提供了一种定义类要封装的信息的方法。 如果使用 @property 声明对象/变量,则导入其类的其他类可以访问该对象/变量。

  • 如果在头文件中使用 @property 声明对象,则必须使用实现文件中的 @synthesize 进行合成。这使对象 KVC兼容。默认情况下,编译器将为此对象合成存取方法

  • 存取方法有:setter和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`
  • 非原子不是线程安全的。您可以使用非原子属性属性来指定合成访问器直接设置或直接返回值,而不保证如果从不同线程同时访问相同的值会发生什么。

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

@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"]; 

名称将不受影响。

  • readonly 如果您不想通过setter方法更改属性,可以只读声明属性。

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

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

与readonly相反。

@property (readwrite) NSString *name;
  • assign 将生成一个setter,它直接将值分配给实例变量,而不是复制或保留它。这最适用于NSInteger和CGFloat等原始类型,或者您不直接拥有的对象,例如委托。

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

@property (assign) NSInteger year;
  • strong 是retain的替代品。

它附带ARC。

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

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

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

该方法应以冒号结束。

@property(setter = boolBool:) BOOL finished;
  • unsafe_unretained Cocoa和Cocoa Touch中有一些类尚不支持弱引用,这意味着您无法声明弱属性或弱局部变量来跟踪它们。这些类包括NSTextView,NSFont和NSColorSpace等。如果需要对这些类之一使用弱引用,则必须使用不安全的引用。

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

@property (unsafe_unretained) NSObject *unsafeProperty;

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

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

答案 1 :(得分:266)

MrMage链接的文章已不再有效。所以,这是我在Objective-C中编写的(非常)短时间内学到的东西:

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

readwrite与readonly - " readwrite"是默认值。 @synthesize时,将为您创建一个getter和一个setter。如果您使用" readonly",则不会创建setter。将它用于在实例化对象后不想改变的值。

保留与复制与分配

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

答案 2 :(得分:146)

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

  
      
  1. atomic // default
  2.   
  3. 非原子
  4.   
  5. strong = retain // default
  6.   
  7. weak = unsafe_unretained
  8.   
  9. 保留
  10.   
  11. assign // default
  12.   
  13. unsafe_unretained
  14.   
  15. 复制
  16.   
  17. 只读
  18.   
  19. readwrite // default
  20.   

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

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

  

Variable property attributes or Modifiers in iOS

以下是文章

中的示例说明
  1. 原子 -Atomic意味着只有一个线程访问变量(静态类型)。 -Atomic是线程安全的。 - 但性能很慢 -atomic是默认行为 - 非垃圾收集环境中的原子访问器(即使用retain / release / autorelease时)将使用锁定  确保另一个线程不会干扰正确设置/获取值。 -it实际上不是关键字。
  2. 示例:

    @property (retain) NSString *name;
    
    @synthesize name;
    
    1. 非原子 -Nonatomic表示多线程访问变量(动态类型)。 -Nonatomic是线程不安全的。 - 但它的性能很快 -Nonatomic不是默认行为,我们需要在属性属性中添加非原子关键字。 当两个不同的进程(线程)同时访问同一个变量时,-it可能会导致意外行为。
    2. 示例:

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

      说明:

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

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

      1. 强大(iOS4 =保留) -it说"把它放在堆里直到我不再指向它了#34; - 换句话说"我是主人,你不能在保留目标之前解决这个问题,因为保留" - 只有在需要保留对象时才使用strong。 - 默认情况下,所有实例变量和局部变量都是强指针。 - 我们通常使用强大的UIViewControllers(UI项目的父母) -strong与ARC一起使用,它基本上可以帮助您,而不必担心对象的保留计数。 ARC完成后会自动为您释放它。使用关键字strong表示您拥有该对象。
      2. 示例:

        @property (strong, nonatomic) ViewController *viewController;
        
        @synthesize viewController;
        
        1. (iOS4 = unsafe_unretained) - 只要其他人强烈地指出它就会保持这种状态" - 与分配相同,不保留或释放 -A"弱" reference是您不保留的引用。 - 我们通常对IBOutlets使用弱(UIViewController' s Childs)。这是有效的,因为只有子对象  只要父对象存在,就需要存在。 弱引用是一种引用,它不保护引用的对象不被垃圾收集器收集。 -Weak本质上是分配,一个没有保留的属性。除了取消分配对象的时间之外,弱指针自动设置为nil
        2. 示例:

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

          强大&弱解释,Thanks to BJ Homer

          想象一下,我们的对象是一只狗,狗想要逃跑(被解除分配)。 强壮的指针就像是狗的皮带。只要你的皮带附着在狗身上,狗就不会逃跑。如果五个人将他们的皮带连接到一只狗,(五个强指针指向一个物体),那么在所有五个皮带脱落之前,狗不会逃跑。 另一方面,弱点就像小孩子指着狗一样说着#34;看!一条狗!"只要狗仍然在皮带上,小孩子仍然可以看到狗,他们仍然会指向它。然而,一旦所有的皮带脱落,无论有多少小孩指着它,狗都会跑开。 一旦最后一个强指针(皮带)不再指向一个对象,该对象将被释放,并且所有弱指针都将被清零。 当我们使用弱者? 你想要使用弱的唯一一次是,如果你想避免保留周期 (例如,父母保留孩子,孩子保留父母,所以两者都没有被释放)。

          1. 保留 =强 -it被保留,旧值被释放并被分配 -retain指定应该在分配时发送新值-retain并发送旧值-release - 就像强者一样。 -apple说如果你写保留它会自动转换/工作只有强大。 - 类似" alloc"包含隐含的"保留"
          2. 示例:

            @property (nonatomic, retain) NSString *name;
            
            @synthesize name;
            
            1. 指定 -assign是默认值,只是执行变量赋值 -assign是一个属性属性,它告诉编译器如何合成属性的setter实现 -I将使用assign表示C原语属性,而weak表示弱对Objective-C对象的引用。
            2. 示例:

              @property (nonatomic, assign) NSString *address;
              
              @synthesize address;
              
              1. <强> unsafe_unretained

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

              2. 示例:

                @property (nonatomic, unsafe_unretained) NSString *nickName;
                
                @synthesize nickName;
                
                1. 复制 当对象是可变的时,需要-copy。 -copy指定应在分配时发送新值-copy并发送旧值-release。 -copy就像retain返回一个对象,你必须在非垃圾回收环境中显式释放(例如,在dealloc中)。 - 如果你使用副本,那么你仍然需要在dealloc中释放它。 - 如果您此时需要对象的值,请使用此选项,并且您不希望该值反映其他人所做的任何更改  对象的所有者。完成后,您需要释放该对象,因为您保留了该副本。
                2. 示例:

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

答案 3 :(得分:8)

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

Nonatomic 表示多线程可以访问该项。线程不安全

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

答案 4 :(得分:0)

优选此链接,了解iOS中Objective-c中的属性...

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