如果我在结构中分离 object ,内存方面会发生什么
What happens in terms of memory if I detach an object in a structure
假设这种情况。我有一个人 class 具有这些属性:
- parent(弱)- 持有对人的引用 parent object
- children (strong) - 是那个人children的数组
- director - 持有标志以标记此人是否是层次结构中的主管的布尔值
然后我有一组员工。只有该公司所有分支机构的 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];
,则不会打印任何内容。
规则是:只要一个对象被另一个对象强引用,就不会被释放。如果不存在更强大的引用,它将被释放。它定义的范围具有强引用(这就是为什么我将代码包装在自动释放池中,否则主要功能将是范围)。
假设这种情况。我有一个人 class 具有这些属性:
- parent(弱)- 持有对人的引用 parent object
- children (strong) - 是那个人children的数组
- director - 持有标志以标记此人是否是层次结构中的主管的布尔值
然后我有一组员工。只有该公司所有分支机构的 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];
,则不会打印任何内容。
规则是:只要一个对象被另一个对象强引用,就不会被释放。如果不存在更强大的引用,它将被释放。它定义的范围具有强引用(这就是为什么我将代码包装在自动释放池中,否则主要功能将是范围)。