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

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

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

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

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


当前回答

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

弱函数类似于赋值,但在它指向的对象被释放后自动设为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.
}

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

其他回答

为了理解强引用和弱引用,考虑下面的例子: 假设我们有一个名为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对象的弱引用。

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

弱函数类似于赋值,但在它指向的对象被释放后自动设为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.
}

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

strong和retain的区别:

在iOS4中,强等于留住 它意味着你拥有该对象,并将其保存在堆中,直到不再指向它为止 如果你写retain,它会像strong一样自动工作


weak和assign的区别:

“弱”引用是指您不保留的引用,只要其他人强烈地指向它,您就会保留它 当对象被“释放”时,弱指针被自动设置为nil “assign”属性属性告诉编译器如何合成属性的setter实现

原子/原子

非原子的比原子的快得多 总是使用nonatomic,除非你对atomic有非常具体的要求,这应该是罕见的(atomic不能保证线程安全-只有当它同时被另一个线程设置时才会暂停访问属性)

强/弱/分配

使用strong来保留对象——尽管关键字retain是同义词,但最好使用strong代替 如果你只想要一个指向对象的指针而不保留它,请使用weak -这有助于避免保留周期(例如。delegate)——当对象被释放时,它会自动空出指针 对原语使用赋值-与weak完全相同,只是它在释放时不会清空对象(默认设置)

(可选)

copy

使用它创建对象的浅拷贝 始终将不可变属性设置为copy的好做法——因为可变版本可以传递到不可变属性中,copy将确保您始终处理不可变对象 如果传入一个不可变对象,它将保留它-如果传入一个可变对象,它将复制它

只读的

使用它来禁用属性的设置(如果存在违规,则防止代码编译) 您可以通过直接通过其实例变量更改变量或在getter方法本身中更改getter所传递的内容