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

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

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

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

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


从过渡到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.
}

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


在阅读了许多Stackoverflow帖子和演示应用程序来检查变量属性属性后,我决定将所有属性信息放在一起:

原子 // 默认的 原子 强=保留/ /违约 弱 保留 分配 // 默认的 unsafe_unretained 复制 只读的 读写 // 默认的

下面是详细的文章链接,在那里你可以找到上面提到的所有属性,这肯定会对你有帮助。 非常感谢所有在这里给出最好答案的人!!

iOS中的可变属性属性或修饰符

1.strong (iOS4 = retain)

it says "keep this in the heap until I don't point to it anymore" in other words " I'am the owner, you cannot dealloc this before aim fine with that same as retain" You use strong only if you need to retain the object. By default all instance variables and local variables are strong pointers. We generally use strong for UIViewControllers (UI item's parents) strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.

例子:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

2.弱 -

it says "keep this as long as someone else points to it strongly" the same thing as assign, no retain or release A "weak" reference is a reference that you do not retain. We generally use weak for IBOutlets (UIViewController's Childs).This works because the child object only needs to exist as long as the parent object does. a weak reference is a reference that does not protect the referenced object from collection by a garbage collector. Weak is essentially assign, a unretained property. Except the when the object is deallocated the weak pointer is automatically set to nil

例子:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

强与弱的解释,感谢BJ Homer:

Imagine our object is a dog, and that the dog wants to run away (be deallocated). Strong pointers are like a leash on the dog. As long as you have the leash attached to the dog, the dog will not run away. If five people attach their leash to one dog, (five strong pointers to one object), then the dog will not run away until all five leashes are detached. Weak pointers, on the other hand, are like little kids pointing at the dog and saying "Look! A dog!" As long as the dog is still on the leash, the little kids can still see the dog, and they'll still point to it. As soon as all the leashes are detached, though, the dog runs away no matter how many little kids are pointing to it. As soon as the last strong pointer (leash) no longer points to an object, the object will be deallocated, and all weak pointers will be zeroed out.

当我们用weak?

你唯一想要使用weak的时候,就是你想避免保留循环的时候 (例如,父元素保留子元素,子元素保留父元素,所以两者都不会被释放)。

3.保留=强大

它被保留,旧的值被释放,它被分配retain指定应该发送的新值 保留赋值和旧值sent -release 保留就等于坚强。 苹果说如果你写retain,它会自动转换/只像strong一样工作。 像alloc这样的方法包含一个隐式的retain

例子:

@property (nonatomic, retain) NSString *name;

@synthesize name;

4.分配

Assign是默认值,它只执行变量赋值 Assign是一个属性属性,它告诉编译器如何合成属性的setter实现 我将对C原语属性使用assign,对Objective-C对象的弱引用使用weak。

例子:

@property (nonatomic, assign) NSString *address;

@synthesize address;

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语义部分。


原子/原子

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

强/弱/分配

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

(可选)

copy

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

只读的

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


strong和retain的区别:

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


weak和assign的区别:

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


强:

属性不会销毁,但只有当你将属性设置为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。

希望这能有所帮助。