如果我在结构中分离 object ,内存方面会发生什么

What happens in terms of memory if I detach an object in a structure

假设这种情况。我有一个人 class 具有这些属性:

然后我有一组员工。只有该公司所有分支机构的 CEO 才被添加到该数组中。员工被添加为 children 到他们各自的老板,具有不同的层次结构。

视觉上是这样的(在此示例中,您只看到数组中添加了一位 CEO):

      JACK (CEO)
          |
   ---------------       
   |              |
  BOB            TOM  
                  |
                  |
              ---------
             |         |
            LAURA    CARRY 
                       |  
                      TONY

看右边的树枝。 Tony 是 Carry 的 child,是 Tom 的 children 之一,也是 Jack 的 child。每个人都对其 child 持有强引用,对其 parent.

持有弱引用

如果我从 Jack 的 children 数组中删除 Tom,内存会发生什么变化?整个分支 Tom、Laura、Carry 和 Tony 从内存中释放,或者我必须断开每个元素之间的所有链接,例如,Carry 和 Tony 之间,Tom 和它的 children 之间,等等

整个分支发布;你不需要再做任何工作了。

实际上,发生的事情是当 Tom 从 Jack 的所有权中释放时,它又会释放它持有的所有强引用,这会在引用树中递归发生。

一个小实验

#import <Foundation/Foundation.h>


@interface Person : NSObject
@property (copy, nonatomic) NSString * name;
@property (strong , nonatomic) NSMutableArray *children;
@property (weak, nonatomic) Person *parent;
@end

@implementation Person

- (instancetype)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        _name = name;
        _children = [@[] mutableCopy];
    }
    return self;
}

-(void)dealloc
{
    NSLog(@"dealloc %@", self.name);
}
@end


int main(int argc, const char * argv[]) {

    //family's scope is the main function. it will exist till the app stops.
    NSMutableArray *family = [@[] mutableCopy];

    @autoreleasepool {

        Person *p0 = [[Person alloc] initWithName:@"father"];
        Person *c1 = [[Person alloc] initWithName:@"child 1"];
        Person *c2 = [[Person alloc] initWithName:@"child 2"];
        [p0.children addObject:c1];
        [p0.children addObject:c2];

        [family addObject:p0];
        [family removeObjectAtIndex:0];
        // p0, c1, c2 are defined in this scope. but family is defined 
        // in the scope of main()
    }
    while (YES) { // needed to give NSLog enough time
    }
    return 0;
}

如果你运行这段代码,它将产生

2015-02-20 18:50:40.618 persons[66846:956945] dealloc father
2015-02-20 18:50:40.619 persons[66846:956945] dealloc child 1
2015-02-20 18:50:40.619 persons[66846:956945] dealloc child 2

如果您删除 [family removeObjectAtIndex:0];,则不会打印任何内容。

规则是:只要一个对象被另一个对象强引用,就不会被释放。如果不存在更强大的引用,它将被释放。它定义的范围具有强引用(这就是为什么我将代码包装在自动释放池中,否则主要功能将是范围)。