Objective-C中强弱之间的差异

时间:2012-06-13 11:08:24

标签: objective-c

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

对象指针的strong声明中weak@property之间有什么区别?

此外,nonatomic是什么意思?

9 个答案:

答案 0 :(得分:685)

考虑气球方面的强弱参考可能会有所帮助。

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

一个强大的参考就像保持一个字符串到那个气球。只要你抓住附在气球上的绳子,它就不会飞走。

弱参考就像看气球一样。你可以看到它,访问它的属性,调用它的方法,但你没有该气球的字符串。如果每个人都拿着绳子放开,那么气球就会飞走,你就再也无法进入了它。

答案 1 :(得分:627)

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

相反,使用弱引用表示您不希望控制对象的生命周期。您引用弱的对象只会继续存在,因为至少有一个其他对象对它有强烈的引用。一旦不再是这种情况,对象就会被破坏,你的弱属性将自动设置为nil。 iOS中最常见的弱引用用例是:

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

  2. 视图控制器主视图的子视图/控件,因为主视图已经强烈保存了这些视图。

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

答案 2 :(得分:22)

strong :为其分配传入值,它将保留传入值并释放实例变量的现有值

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

所以基本的区别在于保留新变量。 通常你想保留它,但有些情况下你不想拥有它,否则你会得到一个保留周期而无法释放对象的内存。例如。 obj1保留obj2,obj2保留obj1。要解决这种情况,请使用弱引用。

答案 3 :(得分:12)

虚假答案: -

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

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

使用Strong: -  保留在 WEAK 中未包含的所有地方。

答案 4 :(得分:8)

,这些关键字围绕Objective-C中的对象所有权

什么是对象所有权?

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

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

只要指针变量指向一个对象,该对象就拥有一个所有者并保持活跃状态​​。这被称为强大引用。

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

请在此处查看详细说明Demystifying @property and attributes

答案 5 :(得分: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

答案 6 :(得分:6)

是默认值。只要存在指向它的强指针,对象就会保持“活着”。

指定不使引用对象保持活动状态的引用。当没有对象的强引用时,弱引用设置为nil。

答案 7 :(得分:2)

要了解强弱参考,请考虑以下示例,假设我们有一个名为displayLocalVariable的方法。

 -(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;),如下所示,

@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的强引用。请参阅下面的代码以了解弱引用,

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

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

现在再次考虑以下代码,

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

在上面的代码中,self.username具有对myName的强引用,因此,即使方法结束后self.dummyName现在也具有myName的值,因为myName具有与其关联的强引用。

现在,只要我们对变量进行强引用,其保留计数就会增加1,并且直到iy的保留计数达到0时,变量才会被释放。

希望这会有所帮助。

答案 8 :(得分:1)

:基本上使用我们用于从/向另一个类获取或发送数据的属性。 :通常所有插座,连接都是接口的弱类型。

Nonatomic :当我们不希望将我们的插座或对象分享到不同的同时线程时,会使用这种类型的属性。换句话说,Nonatomic实例使我们的属性一次处理一个线程。 希望它对你有所帮助。