//
// main.m
// 单个对象的内存管理
//
// Created by admin on 15/8/3.
// Copyright (c) 2015年 admin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Person.h"
void test();
void test5(Person * p);
int main(int argc, const char * argv[]) {
// test();
Person *p = [[Person alloc]init];
test5(p);
[p release];
NSLog(@"%lu",p.retainCount);
[p release];
return 0;
}
void test()
{
Person *p = [[Person alloc]init]; // retainCount = 1
p.age = 10;
NSLog(@"%@", p);
[p release]; // retainCount = 0 对象被回收
[p run];// 通过已经被回收的对象,调用对象的方法,此刻这个指针称之为野指针,这样的调用是错误的
/*
注意:
系统已经将p所指向的对象回收了
EXC_BAD_ACCESS 访问了不可访问的内存空间
被系统回收的对象我们称之为僵尸对象
默认情况下xcode为了提高编码效率,不会实时检查僵尸对象
*/
/*
方法: 为了防止野指针操作,当我们确定当前作用域中的对象不会再被使用了,通常我们会把不再使用的指针变量赋值为nil
*/
p = nil;
p.age = 30; // 那么这两句就表示:nil.age = 30;
[p run]; // [nil run]
}
void test2()
{
/*
内存泄漏: 内存泄漏指,不再被使用的对象,一直在内存中没有被回收
即:只要对象的retainCount != 0 那么这个对象就一直在内存中
*/
// 一下分析两种内存泄漏的情况:
// 内存泄漏的第一种情况:
Person *p = [[Person alloc]init];//retainCount = 1
p.age = 10;
[p retain]; //retainCount = 2
[p retain]; //retainCount = 3
[p release];//retainCount = 2
[p release];//retainCount = 1
// 这里对象的retainCount != 0 对象就不会被销毁,即对象一直在内存中
}
void test3()
{
Person *p = [[Person alloc]init];
p.age = 90;
// 内存泄漏的第二种情况:
[p run];
p = nil;
[p release]; // 这里只是将指向对象的指针赋值为nil了,而这里是[nil release],事实上对象还是在内存中,并没有被释放,并且此时没有指针指向这个对象
}
void test4()
{
Person *p = [[Person alloc]init];
p.age = 80;
Person *p2 = p;
[p release]; // 这里已经将对象销毁
[p2 run]; // 有指针,可是没有对象,所以这里是野指针操作
}
void test5(Person * p)
{
p.age = 50;
NSLog(@"%@",p);
[p retain];
NSLog(@"%lu",p.retainCount);
}
//
// Person.h
// 手动内存管理
//
// Created by admin on 15/8/3.
// Copyright (c) 2015年 admin. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int age;
- (void)run;
@end
//
// Person.m
// 手动内存管理
//
// Created by admin on 15/8/3.
// Copyright (c) 2015年 admin. All rights reserved.
//
#import "Person.h"
@implementation Person
- (void)dealloc
{
[super dealloc];
NSLog(@"对象被销毁了");
}
- (NSString *)description
{
return [NSString stringWithFormat:@"age = %d", _age];
}
- (void)run
{
NSLog(@"人跑起来了");
}
@end
// main.m
// 单个对象的内存管理
//
// Created by admin on 15/8/3.
// Copyright (c) 2015年 admin. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Person.h"
void test();
void test5(Person * p);
int main(int argc, const char * argv[]) {
// test();
Person *p = [[Person alloc]init];
test5(p);
[p release];
NSLog(@"%lu",p.retainCount);
[p release];
return 0;
}
void test()
{
Person *p = [[Person alloc]init]; // retainCount = 1
p.age = 10;
NSLog(@"%@", p);
[p release]; // retainCount = 0 对象被回收
[p run];// 通过已经被回收的对象,调用对象的方法,此刻这个指针称之为野指针,这样的调用是错误的
/*
注意:
系统已经将p所指向的对象回收了
EXC_BAD_ACCESS 访问了不可访问的内存空间
被系统回收的对象我们称之为僵尸对象
默认情况下xcode为了提高编码效率,不会实时检查僵尸对象
*/
/*
方法: 为了防止野指针操作,当我们确定当前作用域中的对象不会再被使用了,通常我们会把不再使用的指针变量赋值为nil
*/
p = nil;
p.age = 30; // 那么这两句就表示:nil.age = 30;
[p run]; // [nil run]
}
void test2()
{
/*
内存泄漏: 内存泄漏指,不再被使用的对象,一直在内存中没有被回收
即:只要对象的retainCount != 0 那么这个对象就一直在内存中
*/
// 一下分析两种内存泄漏的情况:
// 内存泄漏的第一种情况:
Person *p = [[Person alloc]init];//retainCount = 1
p.age = 10;
[p retain]; //retainCount = 2
[p retain]; //retainCount = 3
[p release];//retainCount = 2
[p release];//retainCount = 1
// 这里对象的retainCount != 0 对象就不会被销毁,即对象一直在内存中
}
void test3()
{
Person *p = [[Person alloc]init];
p.age = 90;
// 内存泄漏的第二种情况:
[p run];
p = nil;
[p release]; // 这里只是将指向对象的指针赋值为nil了,而这里是[nil release],事实上对象还是在内存中,并没有被释放,并且此时没有指针指向这个对象
}
void test4()
{
Person *p = [[Person alloc]init];
p.age = 80;
Person *p2 = p;
[p release]; // 这里已经将对象销毁
[p2 run]; // 有指针,可是没有对象,所以这里是野指针操作
}
void test5(Person * p)
{
p.age = 50;
NSLog(@"%@",p);
[p retain];
NSLog(@"%lu",p.retainCount);
}
//
// Person.h
// 手动内存管理
//
// Created by admin on 15/8/3.
// Copyright (c) 2015年 admin. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int age;
- (void)run;
@end
//
// Person.m
// 手动内存管理
//
// Created by admin on 15/8/3.
// Copyright (c) 2015年 admin. All rights reserved.
//
#import "Person.h"
@implementation Person
- (void)dealloc
{
[super dealloc];
NSLog(@"对象被销毁了");
}
- (NSString *)description
{
return [NSString stringWithFormat:@"age = %d", _age];
}
- (void)run
{
NSLog(@"人跑起来了");
}
@end