zoukankan      html  css  js  c++  java
  • ObjectiveC ARC下的内存管理(一)

    Automatic Reference Counting(ARC)是iOS 4.0以上,在Xcode 4.2以上新建工程时可以选择开启的内存管理功能。看上去是可选择功能,但开启后对编程有较大影响,所以值得仔细考究一番。

     

    首先,正如 Automatic Reference Counting名称所表达的意思,自动引用计数并不是垃圾自动回收,并非如JavaScript中,只管声明变量或成员,而由解释器自动地决定其是否释放。

    在ARC下有如下限制:

    release是不可调用的,

    dealloc不可直接调用,并且不能[super dealloc]

    唯一直观的方法是

    str=nil;

    但即使如此,只是之后的代码无法用str去引用原字符串对象而已,原字符串所用内存未必被释放。如以下情况:

    NSString *strTest = [[NSString alloc] initWithFormat:@"%@", @"One!!!" ];

    NSString *strOwned = strTest;

    strTest = nil;

    NSLog(@”%@”, strOwned);

     

    结果是输出 One!!!

    原因是所有声明的对象,默认都是strong,只要对象被strong对象引用一次,count(实际对象计数器)就被加1,上例子中 strTest指向的@"One!!!"被strOwned引用了一次,即使自己被置为nil(ARC世界中表示release,count减一),count依然不为0,所以内存并没有释放,而直到 strOwned=nil的时候,@"One!!!"才真正被释放。

     

    这个释放机制的过程在上面的简单情况中还是很好理解的,那么来看看下面的情况:

       NSString *strTest = [[NSString alloc] initWithFormat:@"%@", @"One!!!" ];

        NSString *strTest2 = [[NSString alloc] initWithFormat:@"%@", @"Two!!!" ];

        NSString *strTest3 = [[NSString alloc] initWithFormat:@"%@", @"Three!!!" ];

        NSString *strTest4 = [[NSString alloc] initWithFormat:@"%@", @"Four!!!" ];

        NSString *strTest5 = [[NSString alloc] initWithFormat:@"%@", @"Five!!!" ];

       NSString *strTest6 = [[NSString alloc] initWithFormat:@"%@", @"Six!!!" ];

        NSString *strTest7 = [[NSString alloc] initWithFormat:@"%@", @"Seven!!!" ];

        array = [[NSMutableArray alloc] init];

        [array addObject:strTest];

        [array addObject:strTest2];

        [array addObject:strTest3];

        [array addObject:strTest4];

        [array addObject:strTest5];

        [array addObject:strTest6];

        [array addObject:strTest7];

     

     

    在某处执行

    [array removeAllObjects];

     

    strTest~ strTest7是否被释放?

    回答这个问题首先要回答,array的对象是否被引用?

    见如下声明:

    NSString *strOwned;

    __weak NSString *strWeak;

    __weak NSString *strWeak2;

    NSString *strStrong;

     

    strOwned = [array objectAtIndex:0];

    strWeak = [array objectAtIndex:1];

    strWeak2 = [array objectAtIndex:2];

    strStrong = strWeak2;

     

    以下输出各是什么?

    清单3

    NSLog(@"%@", strOwned);

    NSLog(@"%@", strWeak);

    NSLog(@"%@", strWeak2);

    NSLog(@"%@", strStrong);

     

    执行

    [array removeAllObjects];

    之后,以上各输出为:

     

     

    这里比较 strWeak 和 strWeak2的结果是比较有意思的,同样是声明为weak,strWeak2只是被strong的strStrong引用过后,所用对象便也无法由来源(这里是array)释放了,这可能也是复杂工程中容易出错的原因吧。

     

    最后,如果array中各字符串对象被另一个类的成员所引用,如下

    myObj = [[MyObject alloc] init];

    myObj.strStrong = strTest6;

    myObj.strWeak = strTest7;

     

    执行

    [array removeAllObjects];

    之后,清单3的执行结果又是如何呢?回答这个问题前,先考虑下 myObj本身是strong还是weak,情况有何不同?

  • 相关阅读:
    [Swift]LeetCode239. 滑动窗口最大值 | Sliding Window Maximum
    [Swift]LeetCode238. 除自身以外数组的乘积 | Product of Array Except Self
    [Java]LeetCode237. 删除链表中的节点 | Delete Node in a Linked List
    [Swift]LeetCode236. 二叉树的最近公共祖先 | Lowest Common Ancestor of a Binary Tree
    [Swift]LeetCode235. 二叉搜索树的最近公共祖先 | Lowest Common Ancestor of a Binary Search Tree
    [Swift]LeetCode233. 数字1的个数 | Number of Digit One
    [Swift]LeetCode232. 用栈实现队列 | Implement Queue using Stacks
    [Swift]LeetCode230. 二叉搜索树中第K小的元素 | Kth Smallest Element in a BST
    [Swift]LeetCode229. 求众数 II | Majority Element II
    [Swift]LeetCode228. 汇总区间 | Summary Ranges
  • 原文地址:https://www.cnblogs.com/wqlblogger/p/3125443.html
Copyright © 2011-2022 走看看