taj*_*hal 3 memory-leaks memory-management objective-c automatic-ref-counting
我把以下最小的例子放在一起,其中Xcode(4.5.2)静态分析器显然没有检测到泄漏,以便验证我对静态分析器的一些观察:
#import <Foundation/Foundation.h>
@interface Foo : NSObject {
NSArray *array;
}
@property (nonatomic, retain) NSArray *array;
- (void)bar;
@end
@implementation Foo
@synthesize array;
- (void)bar
{
// Shouldn't the static analyzer flag this as a leak?
array = [[NSArray alloc] initWithObjects:@"hello", @"world", nil];
}
@end
int main(int argc, const char *argv[])
{
@autoreleasepool {
Foo *foo = [[Foo alloc] init];
[foo bar];
[foo bar];
[foo bar];
[foo release];
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我没有弄错的话,bar
反复调用会泄漏NSArray
实例.当名称暗示它不会bar
创建NSArray
具有+1保留计数的实例.先前分配给array
实例变量的实例将被泄露,因为它从未被释放.
然而,真正令我担忧的是,我在某处读到ARC基本上使用的算法与静态分析器相同.这是否意味着此代码也会在ARC下泄漏?或者,即使没有__strong
限定符或相应的(strong)
属性,ARC也会默认将所有实例变量视为强变量?
没有弧形:
它不会检测泄漏,因为数组是一个实例变量.因此,实例变量数组仍然可访问且有效,因此不会将其分配给保留计数为1的对象.
即使您多次调用该方法,静态分析器也不仅仅足够聪明地知道该数组指向一个保留变量.
静态分析器只是帮助您了解何时在单个方法中泄漏对象.
但尝试改变方法:
- (void)bar
{
// Shouldn't the static analyzer flag this as a leak?
NSArray* array2 = [[NSArray alloc] initWithObjects:@"hello", @"world", nil];
}
Run Code Online (Sandbox Code Playgroud)
这将由静态分析器检测到.
关于ARC
使用ARC时,这段代码没有泄漏,因为当你说array =时,就像你:
所以如果可以,我建议转向ARC.