ARC为属性引入了两个新的内存管理属性,强和弱。

除了复制,这显然是完全不同的东西,强与保留和弱与赋值之间有什么区别吗?

根据我的理解,这里唯一的区别是weak会将nil赋值给指针,而assign不会,这意味着当我向指针发送消息时,程序将崩溃,一旦它被释放。但如果我用weak,这就不会发生,因为message send给nil什么都不会做。

我不知道坚强和保留之间有什么区别。

是否有任何理由,为什么我应该使用分配和保留在新项目,或者是那种被弃用?


当前回答

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

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

在上述方法中,myName变量的作用域仅限于displayLocalVariable方法,一旦方法完成,myName变量将从内存中释放字符串“ABC”。

现在如果我们想在视图控制器生命周期中保持myName变量值。为此,我们可以创建名为username的属性,它将具有对变量myName的强引用(参见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。用户名和自我。用户名对myName有强引用(正如我们在接口中使用@property声明的那样)(间接地,它对“ABC”字符串有强引用)。因此字符串myName直到self才会从内存中被释放。用户名已激活。

弱引用

现在考虑将myName赋值给弱引用dummyName self。dummyName = myName; 与强引用不同,弱引用将只保留myName,直到有对myName的强引用。 请参阅下面的代码以理解弱引用,

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

在上面的代码中,有对myName的弱引用(即。自我。dummyName对myName有弱引用),但没有对myName的强引用,因此是self。dummyName将不能保存myName值。

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

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

在以上代码中自我。username对myName有强引用,因此是self。即使在方法结束后,dummyName现在也会有一个myName值,因为myName有一个与之关联的强引用。

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

希望这能有所帮助。

其他回答

据我所知,坚强和保留是同义词,所以它们的作用完全相同。

弱函数类似于赋值,但在它指向的对象被释放后自动设为nil。

这意味着,你可以简单地更换它们。

但是,我遇到了一个特殊的情况,我必须使用assign,而不是weak。我们有两个属性,delegateAssign和delegateWeak。在这两个中都存储了我们的委托,它通过拥有唯一的强引用来拥有我们。委托正在释放,所以我们的-dealloc方法也被调用。

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething];
    [delegateAssign doSomething];
}

委托已处于释放过程中,但仍未完全释放。问题是对他的弱引用已经被无效了!属性delegateWeak包含nil,但delegateAssign包含有效对象(所有属性已经释放并为空,但仍然有效)。

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething]; // Does nothing, already nil.
    [delegateAssign doSomething]; // Successful call.
}

这是一个非常特殊的例子,但是它告诉我们这些弱变量是如何工作的,以及什么时候它们是无效的。

Clang关于Objective-C自动引用计数(ARC)的文档清楚地解释了所有权限定符和修饰符:

有四个所有权限定符: __autoreleasing 强烈 __ * unsafe_unretained * __weak 如果类型是限定的,则它具有重要的所有权限定 __autoreleased, __strong, or __weak。

声明的属性有六个所有权修饰符:

Assign表示__*unsafe_unretained*所有权。 Copy意味着__strong所有权,以及复制语义在setter上的通常行为。 Retain表示强烈的所有权。 Strong意味着__strong所有权。 *unsafe_unretained*表示__*unsafe_unretained*所有权。 Weak意味着__weak所有权。 除了weak,这些修饰符在非arc模式下可用。

从语义上讲,所有权限定符在读取、赋值、初始化、销毁和移动这五种托管操作中具有不同的含义,其中大多数情况下我们只关心赋值操作的差异。

Assignment occurs when evaluating an assignment operator. The semantics vary based on the qualification: For __strong objects, the new pointee is first retained; second, the lvalue is loaded with primitive semantics; third, the new pointee is stored into the lvalue with primitive semantics; and finally, the old pointee is released. This is not performed atomically; external synchronization must be used to make this safe in the face of concurrent loads and stores. For __weak objects, the lvalue is updated to point to the new pointee, unless the new pointee is an object currently undergoing deallocation, in which case the lvalue is updated to a null pointer. This must execute atomically with respect to other assignments to the object, to reads from the object, and to the final release of the new pointee. For __*unsafe_unretained* objects, the new pointee is stored into the lvalue using primitive semantics. For __autoreleasing objects, the new pointee is retained, autoreleased, and stored into the lvalue using primitive semantics.

read、Init、destroy、Moving的其他区别,请参见文档中4.2语义部分。

强:

属性不会销毁,但只有当你将属性设置为nil时,对象才会被销毁 默认情况下,所有实例变量和局部变量都是强指针。 只有在需要保留对象时才使用strong。 我们通常用strong来表示UIViewControllers (UI项的父项) IOS 4(非arc)我们可以使用保留关键字 IOS 5(ARC)我们可以使用强关键字

例子: @property(强,非原子)

@synthesize viewController;

Weak

默认情况下自动获取并设置为nil

我们通常对iboutlet (UIViewController的子结点)和delegate使用weak 和赋值一样,没有保留或释放

例子: @property(弱,非原子)IBOutlet UIButton *myButton;

@synthesize myButton;

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

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

在上述方法中,myName变量的作用域仅限于displayLocalVariable方法,一旦方法完成,myName变量将从内存中释放字符串“ABC”。

现在如果我们想在视图控制器生命周期中保持myName变量值。为此,我们可以创建名为username的属性,它将具有对变量myName的强引用(参见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。用户名和自我。用户名对myName有强引用(正如我们在接口中使用@property声明的那样)(间接地,它对“ABC”字符串有强引用)。因此字符串myName直到self才会从内存中被释放。用户名已激活。

弱引用

现在考虑将myName赋值给弱引用dummyName self。dummyName = myName; 与强引用不同,弱引用将只保留myName,直到有对myName的强引用。 请参阅下面的代码以理解弱引用,

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

在上面的代码中,有对myName的弱引用(即。自我。dummyName对myName有弱引用),但没有对myName的强引用,因此是self。dummyName将不能保存myName值。

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

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

在以上代码中自我。username对myName有强引用,因此是self。即使在方法结束后,dummyName现在也会有一个myName值,因为myName有一个与之关联的强引用。

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

希望这能有所帮助。

从过渡到ARC发布说明(在属性属性部分的例子)。

// The following declaration is a synonym for: @property(retain) MyClass *myObject;

@property(strong) MyClass *myObject;

所以strong和属性声明中的retain是一样的。

对于ARC项目,我会使用strong而不是retain,我会使用赋值来表示C原语属性,使用weak来表示对Objective-C对象的弱引用。