我在Xcode(分配)中使用分析工具发现的是,当你淘汰一个属性时,在父类被填空之前它不会被释放。现在让我们假设您要确保不在内存中保留昂贵的模态视图控制器(假设它不会经常使用),如果昂贵的VC是属性,则该属性的已分配内存不会当属性被填空时释放,这意味着当用户想再次使用昂贵的VC时,我们每次都会分配相同数量的内存。由于图表不断攀升,因此很容易在剖析器中发现。
然而,如果我只定义了昂贵的VC作为实例变量和定义自己的设定器和放大器;吸气剂分析器分配图实际上降低时立即变量被nilled出来并返回了在每次新的分配相同量的< / p>
所以我的问题是,为什么变量'似乎'在被定义为实例变量时被释放,但在定义为属性时却没有?
// 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
答案 0 :(得分:6)
我不认为你的分析是正确的。如果使用得当,属性和实例变量都会对引用计数产生相同的影响:将其设置为 nil 会减少引用计数器,如果它变为0,则实例(无论是视图控制器还是其他东西)立即被解除分配。
如果您的应用中不是这种情况,那么原因必须是属性与实例变量之外的其他原因。
要进一步分析您的具体问题,我们需要更多信息。因此,请发布您的代码,描述用于测量内存管理效果的设置,有效结果以及您期望的结果。
答案 1 :(得分:0)
所以看起来我只是混淆隐藏/显示昂贵的视图与分配/ nilling,当视图不可见时内存图会下降,反之亦然,我知道真的很傻。
只是为了验证你不能强制arc释放属性/ ivar我创建了一个新的xcode项目,我只是将下面的代码放在didFinishLaunching方法中。不幸的是,分配给属性和ivar的内存保存在内存中,无论我是否将它们取出。在我的情况下,下面的代码生成2.8 MB的内存,当此方法完成并且应用程序启动时,探查器内存图将无限期地保持在2.8MB。
@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;
}