Más contenido relacionado La actualidad más candente (19) Similar a 冲浪 Object-c (11) 冲浪 Object-c2. 内存管理规则
只能释放或自动释放 所拥有的对象
[MyObject alloc]
[MyObject retain];
[MyObject copy];
[MyObject autorelease];
3. 保留计数
Objective-C使用了一 叫做持有计数(Retain Count)的机制来管理内
存中的对象。
创建一个对象,该对象的保留计数为1。
向一个对象发送retain消息时,该对象的保留计数加1。
向一个对象发送release消息时,该对象的保留计数 1。
向一个对象发送autorelease消息时,该对象的保留计数会在
将来的某个阶段 1。
4. 例1:
- (void)printHello {
NSString *string = [[NSString alloc] initWithString:@"Hello"];
NSLog(string);
[string release];
}
/ 用 alloc 创建对象 使 [string releaseCount] = 1
/
5. 例2:
- (void)printHello {
NSString *string; = [NSString stringWithFormat:@"Hello"];
NSLog(string);
}
/ 你拼不拥有 string ,所以你无需 release
/
Q:它们差 在 里?
6. 什么情况下用 autorelease 自动释放?
重点:autorelease并不是“自动释放”,而是“延后释放”,在一个运行周期
后被标记为autorelease会被释放掉。
例1:
– (NSArray *)sprockets {
NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,
auxiliarySprocket, nil];
return [array autorelease];
}
/ 正
/ 使用 autorelease
7. 例2:
– (NSArray *)sprockets {
NSArray *array = [[NSArray alloc]
initWithObjects:mainSprocket,auxiliarySprocket, nil];
return array;
}
/ 内存泄露
/
8. 例3:
– (NSArray *)sprockets {
NSArray *array = [[NSArray alloc]
initWithObjects:mainSprocket,auxiliarySprocket, nil];
[array release];
return array;
}
/ 程序
/ 常退出,因为 array 过早释放
9. 例4:
– (NSArray *)sprockets {
NSArray *array = [NSArray
arrayWithObjects:mainSprocket,auxiliarySprocket, nil];
return array;
}
/ 你并不拥有 arrayWithObjects ,所以你不需要释放
/
12. 例2:
id parent = <#create a parent
object#>;
/ ...
/
heisenObject = [parent child] ;
[parent release];
/ heisenObject 无效
/
13. 例3:
heisenObject = [[array objectAtIndex:n]
retain];
[array removeObjectAtIndex:n];
/ use heisenObject.
/
[heisenObject release];
/ 正常运行
/
14. 集合
例1
NSMutableArray *array;
NSUInteger i;
for (i = 0; i < 10; i++) {
NSNumber *convenienceNumber = [NSNumber numberWithInteger:i];
[array addObject:convenienceNumber];
}
//在这段代码中, 没有调用alloc,因此也没有必要调用release。没有必要
保留新的数字对象(convenienceNumber),因为数组会为 代劳。
15. 例2
NSMutableArray *array;
NSUInteger i;
for (i = 0; i < 10; i++) {
NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger: i];
[array addObject:allocedNumber];
[allocedNumber release];
}
/ 由于数组在用addObject:方法添加数字时对其进行了保留 + 1,因此只要
/
它还在数组中就不会被释放。
16. 从方法返回的对象
例1
- (NSString *)fullName {
NSString *string = [NSString stringWithFormat:@"%@ %@", firstName,
lastName];
return string;
}
// 并不拥有stringWithFormat返回的字符串,所以它可以安全地从该方法
中返回
17. 例2
- (NSString *)fullName {
NSString *string = [[[NSString alloc] initWithFormat:@"%@
%@", firstName, lastName] autorelease];
return string;
}
// 拥有alloc返回的字符串,但 随后向它发送了一条autorelease消
息,因此在 失去它的引用之前, 已经放弃了所有权
18. 例3:
- (NSString *)fullName {
NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",
firstName, lastName] release];
return string;
}
/ 错误
/
19. 例4:
- (NSString *)fullName {
NSString *string = [[NSString alloc] initWithFormat:@"%@ %@",
firstName, lastName];
return string;
}
/ 内存泄露
/
21. MyClass.m:
@synthesize myObject;
-(id)init{
if(self = [super init]){
MyObject * aMyObject = [[MyObject alloc] init];
self.myObject = aMyObject;
[aMyObject release];
}
return self;
}
Q: 为什么要这么 杂的赋值? 为什么要加self. ? 直接写成self.myObject
= [[MyObject alloc] init];不是也没有错么? 不加self有时好像也是正常的?
22. 看以下例子retainCount变化:
间接赋值:
1.加self.:
MyObject * aMyObject = [[MyObject alloc] init]; //aMyObject
retainCount = 1;
self.myObject = aMyObject; //myObject retainCount = 2;
[aMyObject release];//myObject retainCount = 1;
2. 不加self.:
MyObject * aMyObject = [[MyObject alloc] init]; //aMyObject
retainCount = 1;
myObject = aMyObject; //myObject retainCount = 1;
[aMyObject release];//对象己经被释放
23. 直接赋值:
3.加self.:
self.myObject = [[MyObject alloc] init]; //myObject retainCount = 2;
4. 不加self.:
myObject = [[MyObject alloc] init]; //myObject retainCount = 1;
24. MyClass.h
@interface MyClass : NSObject {
MyObject * _myObject;
}
@property (nonatomic, retain) MyObject *myObject;
@end
MyClass.m
@synthesize myObject = _myObject;
如果你用 self._myObject = aMyObject; 或者 myObject = aMyObject;
你会得到一个错误. 为什么 ?
self.myObject = [[MyObject alloc] init]; 为什么会有内存泄露?
26. / retain
/
-(void)setMyObject:(id)newValue{
if (_myObject != newValue) {
[_myObject release];
_myObject = [newValue retain];
}
}
/ copy
/
-(void)setMyObject:(id)newValue{
if (_myObject != newValue) {
[_myObject release];
_myObject = [newValue copy];
}
}
27. 例子
NSString* s = [[NSString alloc]initWithString:@”This is a test string”];
s = [s substringFromIndex:[s rangeOfString:@"a"].location];//内存泄露
[s release];//错误释放
Notas del editor \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n