C strong and weak 的区别

Differences between strong and weak in Objective-C

我刚接触obj-c,所以我的第一个问题是:

strongweak@property声明指向对象的指针时有什么区别?

另外,nonatomic是什么意思?


从气球的角度考虑强引用和弱引用可能会有所帮助。

只要至少有一个人抓住气球上的绳子,气球就不会飞走。持有字符串的人数是保留计数。当没有人抓住绳子时,气球就会飞走(dealoc)。许多人都可以用绳子系在同一个气球上。可以获取/设置具有强引用和弱引用的被引用对象的属性和调用方法。

一个强有力的参照物就像抓住一根绳子,抓住那个气球。只要你抓住气球上的绳子,它就不会飞走。

弱参考就像在看气球。你可以看到它,访问它的属性,调用它的方法,但是气球没有字符串。如果抓住绳子的每个人都松手了,气球就会飞走,你再也无法接近它了。


强引用(在大多数情况下将使用)意味着您要"拥有"使用此属性/变量引用的对象。编译器将注意,只要使用强引用指向任何分配给此属性的对象,它就不会被销毁。只有将属性设置为nil时,对象才会被销毁(除非一个或多个其他对象也具有对它的强引用)。

相反,使用弱引用意味着您不希望控制对象的生命周期。由于至少有一个其他对象拥有对它的强引用,所以您所引用的对象只能生存。一旦不再是这种情况,对象将被销毁,您的弱属性将自动设置为nil。IOS中弱引用最常见的用例是:

  • 委托属性,通常被弱引用以避免保留周期,以及

  • 视图控制器主视图的子视图/控件,因为这些视图已被主视图牢牢保留。

  • 原子与非原子是指编译器为属性合成的getter和setter方法的线程安全性。原子(默认)告诉编译器使访问器方法线程安全(通过在访问IVAR之前添加锁),而非原子则相反。非原子的优点是性能稍高。在iOS上,苹果几乎所有的产品都使用非原子的,所以一般的建议是你也要这样做。


    强:将传入值赋给它,它将保留传入值并释放实例变量的现有值。

    弱:将为其分配传入值而不保留该值。

    所以基本的区别是保留了新的变量。一般来说,您希望保留它,但在某些情况下,您不希望保留它,否则您将获得一个保留周期,并且无法释放对象的内存。例如,obj1保留obj2,obj2保留obj1。为了解决这种情况,您使用弱引用。


    一个虚假的答案:

    我认为上面的答案给出了解释,所以我只想告诉你在哪里使用STRONG,在哪里使用WEAK

    使用WEAK—1。代表们2。经销店三。子视图4。控件等。

    使用STRONG—不包括在WEAK中的所有地方。


    强与弱,这些关键词围绕着Objective-C中的对象所有权展开。

    什么是对象所有权?

    指针变量意味着它们指向的对象的所有权。

    • 当一个方法(或函数)有一个指向一个对象的局部变量时,这个变量就被称为拥有被指向的对象。
    • 当一个对象有一个指向另一个对象的实例变量时,带有指针的对象被称为拥有被指向的对象。

    只要指针变量指向一个对象,该对象就有一个所有者,并且将保持活动状态。这就是所谓的强引用。

    变量可以选择不获取它指向的对象的所有权。不拥有对象所有权的变量称为弱引用。

    请在此处查看详细的解释,以解除@property和attributes的神秘化


    强是默认值。只要有一个指向对象的强指针,它就保持"活动"。

    弱指定不保持被引用对象活动的引用。当没有对对象的强引用时,弱引用设置为零。


    在这里,苹果文档通过各种示例解释了弱属性和强属性之间的区别:

    https://developer.apple.com/library/ios/documentation/cocoa/conceptive/programmingwithobiodic/packamingdata/packamingdata.html//apple_-ref/doc/uid/tp40011210-ch5-sw3

    在这里,在这个博客中,作者已经在同一个地方收集了所有的属性。它将有助于比较性能特征:

    http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html


    为了理解强引用和弱引用,请考虑下面的示例,假设我们有一个名为displaylocalvariable的方法。

    1
    2
    3
    4
    5
     -(void)displayLocalVariable
      {
         NSString myName = @"ABC";
         NSLog(@"My name is = %@", myName);
      }

    在上述方法中,myname变量的作用域仅限于displaylocalvariable方法,一旦方法完成,保存字符串"abc"的myname变量将从内存中释放。

    现在,如果我们想在视图控制器的整个生命周期中保存myname变量值,该怎么办?为此,我们可以创建名为username的属性,该属性将对变量myname具有强引用(见下面代码中的@property(nonatomic,strong) NSString* username;self.username = myName;),如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    @interface LoginViewController ()

    @property(nonatomic,strong) NSString* username;
    @property(nonatomic,weak) NSString* dummyName;

    - (void)displayLocalVariable;

    @end

    @implementation LoginViewController

    - (void)viewDidLoad
    {
        [super viewDidLoad];

    }

    -(void)viewWillAppear:(BOOL)animated
    {
         [self displayLocalVariable];
    }

    - (void)displayLocalVariable
    {
       NSString myName = @"ABC";
       NSLog(@"My name is = %@", myName);
       self.username = myName;
    }

    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
    }


    @end

    现在在上面的代码中,您可以看到myname已经分配给self.username,self.username对myname有一个强引用(正如我们在使用@property的接口中声明的那样)(间接地,它对"abc"字符串有强引用)。因此,在self.username活动之前,字符串myname不会从内存中释放。

    • 弱引用

    现在考虑将myname分配给弱引用dummyname,self.dummyname=myname;与强引用不同,弱引用只保留myname,直到对myname有强引用。请参阅下面的代码以了解弱引用,

    1
    2
    3
    4
    5
    6
    -(void)displayLocalVariable
      {
         NSString myName = @"ABC";
         NSLog(@"My name is = %@", myName);
         self.dummyName = myName;
      }

    在上述代码中,对myname的引用较弱(即self.dummyname对myname的引用较弱),但对myname的引用不强,因此self.dummyname将无法保存myname值。

    现在再次考虑下面的代码,

    1
    2
    3
    4
    5
    6
    7
    -(void)displayLocalVariable
          {
             NSString myName = @"ABC";
             NSLog(@"My name is = %@", myName);
             self.username = myName;
             self.dummyName = myName;
          }

    在上面的代码self.username有一个对myname的强引用,因此self.dummyname现在的值为myname,即使在方法结束之后,因为myname有一个与之相关联的强引用。

    现在,每当我们对一个变量进行强引用时,它的retain count就会增加一个,直到iy的retain count达到0,变量才会被释放。

    希望这有帮助。


    强:基本上用于从其他类获取或发送数据的属性。弱电:通常所有插座、接口的连接都是弱电型。

    非原子性:这种类型的属性在我们不想将出口或对象共享到不同的同时线程的情况下使用。换句话说,非原子实例使我们的属性一次处理一个线程。希望对你有帮助。