黑马程序员—Objective-C基础_内存管理(1)

来源:互联网 发布:淘宝刷钻怎么刷 编辑:程序博客网 时间:2024/05/12 13:44
---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

内存管理范围:任何继承了NSObject的对象,对其他基本数据类型无效。
每个OC对象都有自己的引用计数器,用来表示对象被引用的次数。
每个OC对象内部都有4个字节的存储空间用来存储引用计数器。

使用alloc、new或者copy创建新对象的时候,新对象的引用计数器默认值为1
当一个对象的引用计数器的值为0时,对象占用的内存就会被系统回收。 

引用计数器的用法
1> retain:计数器+1,会返回对象本身
2> release:计数器-1,没有返回值
3> retainCount:获取对象当前的引用计数器的值

对象销毁
当一个对象的引用计数器的值为0时,该对象将被销毁,其占用的内存被系统回收。
当一个对象被回收时,调用dealloc方法。一般情况下会重写dealloc,来释放相关资源。
重写dealloc方法时,有一定要在最后面调用[super dealloc]。
对象被回收之后,其占用的内存不可再用。

内存管理的简单操作
int main()
{
    Person *= [[Person alloc] init]; // 1
    
    [p retain]; // pretain +12
    
    [p release]; // prelease -11
    
    [p release]; // prelease -10
    
    // p.name = @"jack"; // pp
    p = nil// p
   
    return 0;
}
僵尸对象:所占用内存已经被回收的对象,僵尸对象不能使用
野指针:指向僵尸对象的指针,给野指针发送消息会报错(EXC_BAD_ACCESS)
空指针:没有指向任何东西的指针(存储的内容是nil、NULL、0),给空指针发送消息不会报错。

多对象之间的内存管理
使用某个对象,则对该对象做一次retain操作。结束使用时,对该对象做一次release操作
谁retain,谁release;谁alloc,谁release。如下:
@class Dog; // DogDog
@interface Person : NSObject
@property(assign,nonatomic) NSString *name;
@property(assign,nonatomic) int age;
// PersonDogDogdogretain
@property(retain,nonatomic) Dog *dog;
@end
@implementation Person
(void)setDog:(Dog *)dog
{   // dogdog
    if (dog != _dog) {
        // dogdogrelease
        [_dog release];
        // dogretain
        _dog = [dog retain];
    }
}
// deallocrelease PersonDog
(void)dealloc
{
    // retainrelease_dognilNULL0 release,
    [_dog release];
    // deallocdealloc[super dealloc]
    [super dealloc];
}
@end
@class:告诉编译器某个名称是一个类的名称,用于.h文件内,在.m中使用improt包含类的所有内容

@property参数
set方法内存管理相关参数 
retain:release旧值,retain新值(适用于OC对象类型)
assign:直接赋值(默认、适用于非OC对象类型)
copy:release旧值,copy新值(一般用于NSString *)

set、get方法的生成
readwrite:同时生成set方法和get方法的声明与实现(默认)
readonly:只生成get方法的声明与实现

多线程管理
nonatomic:性能高 (一般使用这个值)
atomic      :性能低 (默认值)

set方法和get方法的名称
setter:决定set方法的名称,必须有冒号:
getter:决定get方法的名称 (一般用在BOOL类型) 

对象循环引用中的内存管理
当两个对象互相引用时,在一个对象的@property中使用retain,另一个对象的@property中使用assign
@class Dog; // DogDog
@interface Person : NSObject
@property(assign,nonatomic) NSString *name;
@property(assign,nonatomic) int age;
// PersonDogDogdogretain
@property(retain,nonatomic) Dog *dog;
@end
@implementation Person
(void)setDog:(Dog *)dog
{   // dogdog
    if (dog != _dog) {
        // dogdogrelease
        [_dog release];
        // dogretain
        _dog = [dog retain];
    }
}
// deallocrelease PersonDog
(void)dealloc
{
    // retainrelease_dognilNULL0 release,
    [_dog release];
    // deallocdealloc[super dealloc]
    [super dealloc];
}
@end
@interface Dog : NSObject
// PersonDogPersonretainDogassign
@property(assign,nonatomic) Person *person;
@property(assign,nonatomic) NSString *name;
@end
@implementation Dog
// Dogpersonretainrelease
@end
int main()
{
    // 
    Person *p1 = [[Person alloc] init]; // 1
    Dog *d1 = [[Dog alloc] init]; // 1
    Dog *d2 = [[Dog alloc] init]; // 1
    
    p1.dog = d1; // d12
    d1.person = p1; // p12
    // p1dogd2p1setd1released2retain
    p1.dog = d2; // d11  d22
    [d1 release]; // d10
    [d2 release]; // d21
    [p1 release]; // p10d20
    return 0;
}


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net 

0 0