2

我在 Xcode (Allocations) 中使用分析工具发现的是,当您取消一个属性时,它不会被释放,直到父类被取消。现在假设您要确保不在内存中保留昂贵的模态视图控制器(假设它不会经常使用),如果昂贵的 VC 是一个属性,则为该属性分配的内存不会当属性被取消时释放,这意味着当用户想要再次使用昂贵的 VC 时,我们每次将分配相同数量的内存。这在分析器中很容易发现,因为图表一直在攀升。

但是,如果我只将昂贵的 VC 定义为实例变量并定义我自己的 setter&getter,则分析器分配图实际上会在变量被取消时立即减少,并在每次新分配时以相同的数量返回。

所以我的问题是,为什么一个变量“似乎”在定义为实例变量时被释放,但在定义为属性时却没有?

// What I call defining something as an instance variable:
@interface SomeViewController ()
{
    UIPopoverController *somePopover;
}

// What I call defining something as a property
@property (nonatomic,strong) UIPopoverController *somePopover;

// Nilling out a property which does not get allocated unless it does not have a parent (root node memory graph wise)
self.somePopover = nil;

// Nilling out an instance variable which does make the memory graph in the profiler go down by the same amount it went up
somePopover = nil;

AFAIK,您不能强制对象释放其所有内存,直到其父调用 deallocate 其所有子级都被级联释放.. https://stackoverflow.com/a/7631831/2536815

4

2 回答 2

6

我不认为你的分析是正确的。如果使用得当,属性和实例变量都对引用计数产生相同的影响:将其设置为nil会减少引用计数器,如果它变为 0,则立即释放实例(无论是视图控制器还是其他东西)。

如果您的应用程序不是这种情况,那么原因一定不是属性与实例变量。

为了进一步分析您的具体问题,我们需要更多信息。因此,请发布您的代码,描述用于测量内存管理效果的设置、有效结果是什么以及您的期望。

于 2013-09-07T11:57:27.453 回答
0

因此,似乎我只是将隐藏/显示昂贵的视图与分配/取消混淆了,当视图不可见时内存图会下降,反之亦然,我知道我真的很傻..

只是为了验证您不能强制 arc 释放属性/ivar,我创建了一个新的 xcode 项目,我只是将下面的代码放在 didFinishLaunching 方法中。不幸的是,无论我是否将它们归零,分配给属性和 ivar 的内存都保留在内存中。在我的情况下,下面的代码生成 2.8 MB 内存,当此方法完成并且应用程序启动探查器内存图时,它会无限期地保持在 2.8 MB。

@interface SSAppDelegate ()
{
    NSMutableArray *ivVC;
}
@property (nonatomic, strong) NSMutableArray *propertyVC;
@end
@implementation SSAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{



for (int k=0; k<10; k++) {
    ivVC = [NSMutableArray array]; // Doesn't matter if it's alloc] init]
    self.propertyVC = [NSMutableArray array]; 

    for (int i=0; i<1000;i++) {
        [ivVC addObject:@"..................................................................................."];
        [_propertyVC addObject:@"..................................................................................."];

    }

    ivVC = nil;
    self.propertyVC = nil;
}

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
于 2013-09-08T16:37:51.237 回答