内存管理高级--代码

2023-05-30,,

创建Person类,添加两个属性,实例方法,便利构造器,和一个无返回值方法

main.m中

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        
        NSString *name = [[NSString alloc] initWithFormat:@"刘亚方"]; //name开辟空间
        Person *p = [[Person alloc] init];  //类开辟空间
        
        [p setName:name]; //p-->name   (.m中 ,,_name = name;|)
        [name release];   //  释放name ...那么p就变成了野指针,,,解决方法[name retain]
        NSString *newName = [[NSString alloc] initWithFormat:@"六小二"];//重新定义空间newName
        [p setName:newName];  // p-->newName存泄漏。。。。原来的name没有指向了,解决方法 [_name release];
        [p sayHi];       //如果是在常量区,两个地址一样的时候。那么就要加个判断,如果一样就直接使用if (_name != name){},如果不一样就清空,然后retain。。。
        
        [p release];
          //疑问?始终有一块内存没有释放掉。。。。。。。
        //野指针(指针指向空内存)  - [retain]  ---
        //重新定义-- 内存泄漏(原来的name没有指针指向)。解决方法 [_name release];   原来的_name = nil  那么[_name release];  相当于什么都没有做
        //这里是在常量区,两个地址一样的时候。那么就要加个判断,如果一样就直接使用if (_name != name){}
    }
    return 0;
}

Person. h中

#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic , copy)NSString *name;
@property (nonatomic , assign)NSInteger age;
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age;
- (void)sayHi;
@end

Person.m中

#import "Person.h"

@implementation Person
@synthesize name = _name;
@synthesize age = _age;
- (void)dealloc
{
    [_name release];
    [super dealloc];
}
//- (void)setName:(NSString *)name
//{
//    [_name release];
//    _name = [name retain];
//}
- (void)setName:(NSString *)name
{
    if (_name != name) {  //这里是在常量区,两个地址一样的时候。那么就要加个判断,如果一样就直接使用
        [_name release];
        _name = [name copy];
    }
}
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age
{
    self = [super init];
    if (self) {
        self.name = name;
        self.age = age;
    }
    return self;
}
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age
{
    Person *p = [[Person alloc] initWithName:name age:age];
    return [p autorelease];   //用完后,遇到autoreleasepool池自动释放;
//    return [[[Person alloc] initWithName:name age:age] autorelease];   //也可以这样简写
}
- (void)sayHi
{
    NSLog(@"name :%@",_name);
}
@end


任何一个对象都有一个或多个拥有者,只要有一个对象指向他就一直存在,  如果对象没有拥有者,那么这个运行时系统自动销毁,为了保证清楚你的内存,定下以下法则:

  1.  你拥有任何你创建的对象---

  2. 你使用来retain就可以获得这个对象的所有权 -valid

  3. 当你不再使用你创建的对象的时候,你必然把所有权归还回去。。(release)(autorelease)两种方式   “releasing” an object.

  4. 你不能释放你没有拥有的对象  //You must not relinquish ownership of an object you do not own


1.内存管理的黄金法则:The basic rule to apple is everything thatincreases the reference counter with alloc,[mutable]copy[WithZone:] or retain is in charge of the corresponding [auto]release. 即:如果一个对象使用了alloc,[mutable] copy,retain,那么你必须使用相应的release或autonrelease.


2.规则:

1、Objective-C类中实现了引用计数器,对象知道自己当前被引用的次数

2、最初对象的计数器为1

3、如果需要引用对象,可以给对象发送一个retain消息,这样对象的计数器就加1

4、当不需要引用对象了,可以给对象发送release消息,这样对象计数器就减1

5、当计数器减到0,自动调用对象的dealloc函数,对象就会释放内存

6、计数器为0的对象不能再使用release和其他方法


3.内存问题主要有:内存溢出 内存过渡释放 野指针 三种

内存溢出(内存堆积):大量的开辟空间但并不立即释放,通常是由于使用autorelease产生的.

内存过渡释放:对象将内存已经还给系统,之后再次归还给系统这时就会出现内存过渡释放的问题.

野指针:对象指向的内存空间已经归还给系统但此时再次调用了指向该指针空间的指针,就会产生野指针的问题.


4.内存管理的形式:MRC (manual reference count) 人工引用计数机制 内存的开辟和释放都有手动代码进行控制.ARC(auto reference count )自动引用计数机制 不需要人工控制系统自动进行管理.

《内存管理高级--代码.doc》

下载本文的Word格式文档,以方便收藏与打印。