标签:
- (void )setWindow:(UIWindow *)window
{
_window = window;
}
// AppDelegate.m
// 因为是assign,所以不会对[[UIWindow alloc]init]产生的对象做retain操作. 在自动释放池释放时,引用计数器会由1变成0,AppDelegate不能长期拥有该Window
self.window = [[[UIWindow alloc]init]autorelease];
//既然自动释放池释放时,会把产生的Window销毁,不添加autorelease呢?这样不符合内存管理原则,这么做意味着,产生的Window永远无法销毁
self.window.backgroundColor = [UIColor redColor];
self.window.frame = [UIScreen mainScreen].bounds;
[self.window makeKeyAndVisible];
return YES;
// 如果用下面修改上面的代码为下面这样,貌似AppDelegate既可以长期拥有Window,AppDelegate释放时,也可以销毁Window
self.window = [[UIWindow alloc]init];
// 潜在问题是,如果对self.window重复赋值,例如再写一行代码 self.window = [[UIWindow alloc]init]. AppDelegate释放时,就无法销毁旧的Window
self.window.backgroundColor = [UIColor redColor];
self.window.frame = [UIScreen mainScreen].bounds;
[self.window makeKeyAndVisible];
return YES;
- (void)dealloc{
[self.window release];
[super dealloc];
}
- (void )setWindow:(UIWindow *)window
{
if (_window != window) {
[_window release];
_window = [window retain];
}
}
// AppDelegate.m
// 因为是retain,所以会对[[UIWindow alloc]init]产生的对象做retain,在自动释放池释放时,会由2变成1,AppDelegate可以长期拥有该Window
self.window = [[[UIWindow alloc]init]autorelease];
self.window.backgroundColor = [UIColor redColor];
self.window.frame = [UIScreen mainScreen].bounds;
[self.window makeKeyAndVisible];
return YES;
// 为了防止内存泄露,在AppDelegte销毁的时候,要对拥有的window做release操作
- (void)dealloc{
[self.window release];
[super dealloc];
}
-------------Dog----------Begin-------------
#import <Foundation/Foundation.h>
@interface Dog : NSObject
@end
#import "Dog.h"
@implementation Dog
- (void)dealloc
{
NSLog(@"Dog--dealloc");
[super dealloc];
}
@end
-------------Dog----------End-------------
-------------Person----------Begin-------------
#import <Foundation/Foundation.h>
@class Dog;
@interface Person : NSObject
{
Dog *_dog;
}
- (void)setDog:(Dog *)dog;
- (Dog *)dog;
@end
#import "Person.h"
@implementation Person
- (void)setDog:(Dog *)dog
{
_dog = dog;
}
- (Dog *)dog
{
return _dog;
}
- (void)dealloc
{
NSLog(@"Person--dealloc");
[super dealloc];
}
@end
-------------Person----------End-------------
-------------MainViewController----------Begin-------------
Dog *d = [[Dog alloc]init];
Person *p =[[Person alloc]init];
p.dog = d;
[d release];
NSLog(@"p.dog----%@",p.dog); //僵尸对象
[p release];
-------------MainViewController----------End-------------
2.3 优化,解决僵尸对象的问题
修改Person的Set方法
- (void)setDog:(Dog *)dog
{
_dog = [dog retain]; // 这样MainViewController就不会访问僵尸对象
}
- (void)dealloc
{
NSLog(@"Person--dealloc");
[self.dog release]; //谁retain,谁release
[super dealloc];
}
2.4 存在的问题:重复赋值时,Person销毁时,只能释放最新持有的Dog,旧Dog内存泄露
Dog *d = [[Dog alloc]init];
Dog *d2 = [[Dog alloc]init];
Person *p =[[Person alloc]init];
p.dog = d;
p.dog = d2;
[d release];
NSLog(@"p.dog----%@",p.dog);
[p release];
- (void)setDog:(Dog *)dog
{
[_dog release];
_dog = [dog retain];
}
Dog *d = [[Dog alloc]init];
Person *p =[[Person alloc]init];
p.dog = d;
p.dog = d; // 执行到这一行时,会出现野指针错误
[d release];
NSLog(@"p.dog----%@",p.dog);
[p release];
- (void)setDog:(Dog *)dog
{
if (_dog != dog) {
[_dog release];
_dog = [dog retain];
}
}
@interface Person : NSObject
@property (retain,nonatomic) Dog *dog;
@end
1>要长期持有一个属性用retain. 注:一般情况,属性除了UI控件,一般都是想长期持有的
2>在dealloc方法里,要释放:
写法一:[self.属性名 release];
_属性名 = nil;
写法二:[_属性名 release];
_属性名 = nil;
写法三:[self.属性名 nil];
5.
标签:
原文地址:http://www.cnblogs.com/oumygade/p/4281367.html