关于IOS:Objective-C Arc:strong vs retain and weak vs assignation

Objective-C ARC: strong vs retain and weak vs assign

ARC引入的属性有两个新的内存管理属性:strongweak

除了copy明显完全不同之外,strongretainweakassign之间有什么区别吗?

据我所知,这里唯一的区别是,weak将把nil分配给指针,而assign将不会,这意味着一旦指针被释放,当我向它发送消息时,程序将崩溃。但如果我使用weak,这永远不会发生,因为发送到nil的消息不会做任何事情。

我不知道strongretain之间有什么区别。

我为什么要在新项目中使用assignretain,有什么理由吗?或者这种类型的项目被否决了吗?


在阅读了大量StackOverflow文章和演示应用程序以检查变量属性之后,我决定将所有属性信息放在一起:

  • 原子//默认
  • 非原子的
  • 强=保留//默认
  • 虚弱的
  • 保持
  • 分配//默认
  • 不安全的
  • 复制
  • 只读
  • 读写//默认
  • 下面是详细的文章链接,您可以在其中找到上面提到的所有属性,这绝对会帮助您。非常感谢所有在这里给出最佳答案的人!!

    Variable property attributes or Modifiers in iOS

    1.强(ios4=保留)

    • 上面写着"把这个放在堆里,直到我不再指向它"
    • 换言之,"我是所有者,你不能在目标明确之前就把它处理掉,就像保留一样"
    • 只有在需要保留对象时才使用强。
    • 默认情况下,所有实例变量和局部变量都是强指针。
    • 我们通常对uiviewcontrollers(ui项的父项)使用strong
    • STRONG与ARC一起使用,它基本上可以帮助您不必担心对象的保留计数。完成后,ARC会自动释放它。使用关键字STRONG表示您拥有对象。

    例子:

    1
    2
    3
    @property (strong, nonatomic) ViewController *viewController;

    @synthesize viewController;

    2.弱-

    • 上面写着"只要有人强烈地指向它,就保持这个"
    • 与分配相同,不保留或释放
    • "弱"引用是指不保留的引用。
    • 我们通常对iboutlets(uiviewcontroller的子对象)使用weak,这是因为子对象只需要与父对象一样存在。
    • 弱引用是不保护被引用对象不被垃圾收集器收集的引用。
    • 弱本质上是分配的,是不包含的属性。除非当对象被释放时,弱指针自动设置为零

    例子:

    1
    2
    3
    @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.

    当我们使用弱者?

    唯一一次你想使用弱的,是如果你想避免保留周期(例如,父母保留了孩子,而孩子保留了父母,所以两人都没有被释放)。

    3.保留=强

    • 它被保留,旧值被释放,并且它被分配保留指定应该发送新值
    • 保留分配和发送的旧值-释放
    • 保留与强保留相同。
    • 苹果公司说,如果你写"保留",它将自动转换/工作像强。
    • "alloc"等方法包含隐式"retain"

    例子:

    1
    2
    3
    @property (nonatomic, retain) NSString *name;

    @synthesize name;

    4.分配

    • 赋值是默认值,只需执行变量赋值
    • assign是一个属性属性,它告诉编译器如何合成属性的setter实现。
    • 我将使用assign表示c基元属性,使用weak表示对objective-c对象的弱引用。

    例子:

    1
    2
    3
    @property (nonatomic, assign) NSString *address;

    @synthesize address;


    从过渡到ARC发行说明(属性属性部分中的示例)。

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

    @property(strong) MyClass *myObject;

    因此,strong在财产申报中与retain相同。

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


    据我所知,strongretain是同义词,所以它们的作用完全相同。

    然后,weak几乎与assign相似,但在对象(它指向的对象)被释放后,会自动设置为nil。

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

    但是,我遇到了一个特殊的情况,我必须使用assign,而不是weak。假设我们有两个属性:delegateAssigndelegateWeak。在这两者中都存储了我们的委托,即通过拥有唯一的强引用来拥有我们。委托正在解除分配,因此也调用了我们的-dealloc方法。

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

    委托已在解除分配过程中,但尚未完全解除分配。问题是,weak提到他的话已经无效了!属性delegateWeak包含零,但delegateAssign包含有效对象(所有属性都已发布和无效,但仍然有效)。

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

    这是非常特殊的情况,但它向我们揭示了这些weak变量是如何工作的,以及它们何时无效。


    完备/原子

    • 完备原子比是多快
    • 除非你有一个永远使用完备的需求甚为特异性(原子,稀土原子which should be不保证线程安全accessing only the property摊位的时候被另一个线程simultaneously集模式)

    强/弱/ assign

    • 使用强的目标,尽管保留保留synonymous is the keyword是最佳的使用,而不是强
    • 如果你只想使用弱指针to the对象没有保留在保留avoid useful for回圈EN(EN将IE。delegates)automatically when the out the指针nil对象是释
    • 使用assign for primatives -确切的说因为是除了它的零类弱不释(when the out对象集的默认模式)

    (可选的)copy

    • 使用EN for creating a copy of the浅对象
    • 良好的实践集immutable Properties To copy to永远-因为mutable versions passed can be into immutable properties,copy,将保证你永远是处理对象immutable with an
    • 如果对象是passed immutable安在,它将保留它在mutable如果对象是在passed EN,EN will copy

    只读

    • 使用it to disable setting of the property(如果有prevents队列从compiling安infraction)
    • You can change什么交付模式变量模式或者the changing the directly吸气路径或其实例变量,方法本身在吸气剂


    Clang关于Objective-C Automatic Reference Counting(ARC)的文档清楚地解释了所有权限定符和修饰符:

    There are four ownership qualifiers:

    • __autoreleasing
    • __strong
    • __*unsafe_unretained*
    • __weak

    A type is nontrivially ownership-qualified if it is qualified with
    __autoreleasing, __strong, or __weak.

    然后声明的财产有六个所有权修饰符:

    • assign implies __*unsafe_unretained* ownership.
    • copy implies __strong ownership, as well as the usual behavior of copy semantics on the setter.
    • retain implies __strong ownership.
    • strong implies __strong ownership.
    • *unsafe_unretained* implies __*unsafe_unretained* ownership.
    • weak implies __weak ownership.

    With the exception of weak, these modifiers are available in non-ARC modes.

    从语义上讲,所有权限定符在五个托管操作中有不同的含义:读取、分配、初始化、销毁和移动,在这五个操作中,大多数时候我们只关心分配操作的不同。

    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.

    在阅读、初始化、销毁和移动方面的其他差异,请参阅文档中的第4.2节语义。


    为了理解强引用和弱引用,请考虑以下示例:假设我们有一个名为displaylocalvariable的方法。

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

    在上述方法中,myname变量的作用域仅限于displaylocalvariable方法,一旦方法完成,保存字符串"abc"的myname变量将从内存中释放。

    现在,如果我们想在视图控制器的整个生命周期中保存myname变量值,该怎么办?为此,我们可以创建名为username的属性,该属性将具有对变量myname的强引用(见下面代码中的self.username = myName;),如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    @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。请参阅下面的代码以了解弱引用,

    1
    2
    3
    4
    5
    6
    -(void)displayLocalVariable
      {
         NSString myName = @"ABC";
         NSLog(@"My name is = %@", myName);
         self.dummyName = myName;
      }

    在上述代码中,对myname的引用较弱(即self.dummyname对myname的引用较弱),但对myname的引用不强,因此self.dummyname将无法保存myname值。

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

    1
    2
    3
    4
    5
    6
    7
    -(void)displayLocalVariable
          {
             NSString myName = @"ABC";
             NSLog(@"My name is = %@", myName);
             self.username = myName;
             self.dummyName = myName;
          }

    在上面的代码self.username有一个对myname的强引用,因此self.dummyname现在的值为myname,即使在方法结束之后,因为myname有一个与之相关联的强引用。

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

    希望这有帮助。


    强:

    • Will not only but property set the盎司毁掉你…to get the property将destroyed对象
    • 默认的模式是变量和局部变量/分强。
    • 如果你只使用你强need to the对象保留。
    • 我们使用强大的generally for uiviewcontrollers(IU item' S的父母)
    • (不含4 -弧),我们可以使用保留关键字
    • 含5(ARC),我们可以使用强大的关键字

    实例:@(强、性能完备viewcontroller viewcontroller)*;P></

    synthesize viewcontroller";P></弱

    get to automatically by和默认的零集P></

    • 我们使用弱generally for iboutlets(S uiviewcontroller' Childs)和转授
    • assign as the same thing,不保留或释放

    实例:@(弱完备产权,再次显示iboutlet uibutton)*;P></

    "synthesize再次显示;P></


    between the之间的强和保留:P></

    • 在iOS4 is to强烈保留,等
    • 恩,你自己的对象和the means until the堆中的keep to恩不点了
    • 如果你只是写它会自动保留强类工件

    之间的弱和assign between the:P></

    • 在"弱"参考参考是不保留,你只要把你的分/人*强
    • "释放"when the object is,is automatically弱指针到零集
    • "assign"how to the property属性tells编译器执行的synthesize the property'二传手