我关闭了ARC。
我在这样声明的类中有一个属性:
@property(copy) NSString* name
我使用常量字符串设置name
:
[greeter setName:@"Jane"];
我为我的班级实施了dealloc
:
-(void)dealloc{
[super dealloc];
}
我预计会有内存泄漏,因为我没有发布name
。我正在使用Xcode 6.2并且Product>Analyze
没有识别任何泄漏,仪器也没有:Product>Profile, choose Leaks, hit the red Record button
。
以下是相关代码:
//
// Greeter.h
// Flashlight2
//
#import <Foundation/Foundation.h>
@interface Greeter : NSObject
@property(copy) NSString* name;
-(NSString*)description;
-(void)dealloc;
@end
...
//
// Greeter.m
// Flashlight2
//
#import "Greeter.h"
@implementation Greeter
-(NSString*)description {
NSString* msg = [[NSString alloc] initWithString:@"I am a Greeter"];
return [msg autorelease];
}
-(void)dealloc{
[super dealloc];
}
@end
...
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
Greeter* greeter = [[Greeter alloc] init];
[greeter setName:@"Jane"]; //constant string in memory for life of program
NSLog(@"%@", greeter);
[greeter release];
return YES;
}
在考虑了一段时间之后,我能想到的唯一解释是name setter
实际上 复制常量字符串。似乎Obj-C对the string being assigned
对属性进行了类型检查,并且因为它是一个常量字符串,Obj-C只是将(?)the-pointer-to-the-constant-string
赋给name-pointer
。是这样的吗?
答案 0 :(得分:10)
这里有两个优化组合起来导致这个结果。
首先:NSString文字存储在二进制文件的特殊段中,而不是在运行时分配。它们忽略保留和释放,并且从不分配或取消分配。
第二:复制不可变的NSString(包括字符串文字)而不是保留它,因为副本将保证始终与原始版本相同。 (这是通过覆盖私有NSString子类中的-retain和-release方法来实现的)
因此,在您的场景中,副本变为保留,保留被忽略,即使您在dealloc中正确释放字符串,也不会发生释放。