【问题标题】:Differences between strong and weak in Objective-CObjective-C中强弱的区别
【发布时间】:2012-06-16 08:01:42
【问题描述】:

我是 Obj-C 的新手,所以我的第一个问题是:

@property对象指针声明中strongweak有什么区别?

另外,nonatomic 是什么意思?

【问题讨论】:

  • 其实这是一个很好的问题,有时,我们忘记了强/弱和原子/非原子偏好的基本概念...... :) 谢谢你提醒我们......跨度>
  • @JackyBoy 有趣的是,在谷歌上提出的简单搜索将我引到这里哈哈。 #循环引用
  • 我倾向于不相信谷歌上的许多答案,但总是参考 S.O 以获得智能答案

标签: objective-c


【解决方案1】:

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

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

强引用就像抓住气球的绳子。只要你抓住气球上的绳子,它就不会飞走。

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

【讨论】:

  • +2(如果我可以的话)。说真的,非常有创意的解释!
  • 经过 1 年半的 iOS 开发,我想刚才我清楚地理解了 strongweak 的真正含义。
  • @X.Li 保留循环就像你有 2 个字符串给气球,其中一个是你所有的(所以你拥有这个气球),另一个是气球所有的(所以这个气球拥有你)。既然你只能接触到你的绳子,如果气球不想走,你怎么让气球走?所以最好你拥有气球(强),而气球不拥有你(弱)。当你想放手的时候,只要剪断绳子:)
  • 阅读他的个人资料,他是一名 iOS 讲师。很有创意的解释!!脱帽致敬:)
  • 原子与非原子 我认为可以描述为一个多门的公共厕所,中间有一个厕所。一旦有人从一扇门进入厕所,如果他不想经历尴尬的时刻,他还不如将其他所有门都锁在厕所里。哈哈。感谢您阅读这个无意义的类比。
【解决方案2】:

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

相反,使用弱引用表示您不想控制对象的生命周期。您弱引用的对象仅存在,因为至少有一个其他对象持有对它的强引用。一旦不再是这种情况,对象就会被销毁,并且您的弱属性将自动设置为nil。 iOS 中最常见的弱引用用例是:

  1. 委托属性,通常被弱引用以避免保留循环,以及

  2. 视图控制器的主视图的子视图/控件,因为这些视图已经被主视图强占。

原子与非原子是指编译器为属性综合的 getter 和 setter 方法的线程安全性。 atomic (默认)告诉编译器使访问器方法线程安全(通过在访问 ivar 之前添加锁),而 nonatomic 则相反。非原子的优点是性能稍高。在 iOS 上,Apple 对其几乎所有属性都使用非原子,因此一般建议您也这样做。

【讨论】:

  • @Bourne:这取决于您所说的线程安全性。 atomic 保证 property 可以同时从多个线程安全地读取和写入。这并不意味着属性全部为atomic 的对象自动是线程安全的。
  • 很棒的细节。我想我直到现在才真正明白。谢谢。
  • 根据苹果文档,原子和非原子应该是线程安全的同义词。 developer.apple.com/library/ios/documentation/cocoa/conceptual/…
  • "注意:属性原子性不是对象线程安全的同义词。" developer.apple.com/library/ios/documentation/cocoa/conceptual/…
  • 为什么不直接删除不需要的实例?为什么我们不能直接从气球中取出空气或在我们不想要的时候将其摧毁,为什么我们必须关心附带的字符串?我们只需要数据。
【解决方案3】:

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

weak:将传入的值分配给它而不保留它。

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

【讨论】:

    【解决方案4】:

    一个虚拟的答案:-

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

    使用Weak :- 1. 代表 2. 奥特莱斯 3. 子视图 4.控件等

    使用Strong :- WEAK 中未包含的任何地方都剩余。

    【讨论】:

    • 等包含什么:P
    • webView、mapView等
    • 其实大部分我们在storyboard上拖拽的子视图
    【解决方案5】:

    strong>weak,这些关键字围绕Objective-C中的Object Ownership

    什么是对象所有权?

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

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

    任何时候指针变量指向一个对象,该对象都有一个所有者并且将保持活动状态。这称为strong参考。

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

    在这里查看详细解释Demystifying @property and attributes

    【讨论】:

      【解决方案6】:

      这里,Apple 文档使用各种示例解释了弱属性和强属性之间的区别:

      https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3

      在这里,在此博客中,作者已将所有属性收集在同一位置。这将有助于比较属性特征:

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

      【讨论】:

        【解决方案7】:

        strong 是默认设置。只要有指向它的强指针,对象就会保持“活动”。

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

        【讨论】:

          【解决方案8】:

          要理解强引用和弱引用,请考虑以下示例,假设我们有名为 displayLocalVariable 的方法。

           -(void)displayLocalVariable
            {
               UIView* myView = [[UIView alloc] init];
               NSLog(@"myView tag is = %ld", myView.tag);
            }
          

          在上述方法中,myView 变量的作用域仅限于 displayLocalVariable 方法,一旦方法完成,持有 UIView 对象的 myView 变量将从内存中释放。

          现在,如果我们想在视图控制器的整个生命周期中保存 myView 变量怎么办。为此,我们可以创建名为 usernameView 的属性,该属性将对变量 myView 进行强引用(参见下面代码中的 @property(nonatomic,strong) UIView* usernameView;self.usernameView = myView;),如下所示,

          @interface LoginViewController ()
          
          @property(nonatomic,strong) UIView* usernameView;
          @property(nonatomic,weak) UIView* dummyNameView;
          
          - (void)displayLocalVariable;
          
          @end
          
          @implementation LoginViewController
          
          - (void)viewDidLoad
          {
              [super viewDidLoad];
          
          }
          
          -(void)viewWillAppear:(BOOL)animated
          {
               [self displayLocalVariable];
          }
          
          - (void)displayLocalVariable
          {
             UIView* myView = [[UIView alloc] init];
             NSLog(@"myView tag is = %ld", myView.tag);
             self.usernameView = myView;
          }
          
          - (void)didReceiveMemoryWarning
          {
              [super didReceiveMemoryWarning];
          }
          
          
          @end
          

          现在在上面的代码中,您可以看到 myView 已分配给 self.usernameView 并且 self.usernameView 对 myView 具有强引用(正如我们在接口中使用 @property 声明的那样)。因此,在 self.usernameView 存活之前,myView 不会从内存中释放。

          • 弱参考

          现在考虑将 myName 分配给作为弱引用的 dummyNameView,self.dummyNameView = myView; 与强引用不同,Weak 将只保留 myView,直到有对 myView 的强引用。看下面的代码来理解弱引用,

          -(void)displayLocalVariable
            {
               UIView* myView = [[UIView alloc] init];
               NSLog(@"myView tag is = %ld", myView.tag);
               self.dummyNameView = myView;
            }
          

          在上面的代码中有对 myView 的弱引用(即 self.dummyNameView 对 myView 有弱引用)但没有对 myView 的强引用,因此 self.dummyNameView 将无法保存 myView 值。

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

          -(void)displayLocalVariable
                {
                   UIView* myView = [[UIView alloc] init];
                   NSLog(@"myView tag is = %ld", myView.tag);
                   self.usernameView = myView;
                   self.dummyNameView = myView;
                } 
          

          在上面的代码中 self.usernameView 有一个对 myView 的强引用,因此 self.dummyNameView 现在即使在方法结束后也会有一个 myView 的值,因为 myView 有一个与之关联的强引用。

          现在,每当我们对变量进行强引用时,它的保留计数都会增加 1,并且在保留计数达到 0 之前,该变量不会被释放。

          希望这会有所帮助。

          【讨论】:

          • 2019-07-25 12:33:15.479002+0530 StrongAndWeak[6329:245483] 我的名字是 = ABC 2019-07-25 12:33:15.479226+0530 StrongAndWeak[6329:245483] 我的name 是 strong = ABC 2019-07-25 12:33:15.479418+0530 StrongAndWeak[6329:245483] 我的名字是 weak = ABC 你告诉弱属性没有 myname 的值。但我得到了 myname两个参考文献的价值都为 ABC ......?你能给出更明确的答案吗......提前谢谢
          • @Raviteja_DevObal ARC 不承诺立即执行此操作(即解除分配字符串 @"ABC"),但稍后肯定会解除分配...
          • @Raviteja_DevObal As Explain here 字符串是一个不好的例子。我已经用 UIView 对象更新了我的答案,希望对您有所帮助。
          【解决方案9】:

          :基本上与我们用来从/向其他类获取或发送数据的属性一起使用。 :通常所有的出口、连接都是来自接口的弱类型。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-08-27
            • 1970-01-01
            • 2012-02-14
            • 2012-04-06
            • 2011-11-10
            • 1970-01-01
            相关资源
            最近更新 更多