ios 内存管理基础知识

来源:互联网 发布:长春知行科技有限公司 编辑:程序博客网 时间:2024/06/11 03:28

先简单解释一下nil和release的作用:nil就是把一个对象的指针置为空,只是切断了指针与内存中对象的联系;而release才是真正通知内存释放这个对象。所以nil并没有释放内存,只有release才回真正释放内存。一个对象在release之后,给它所分配的内存就已经被释放了,如果释放之后系统再用到这个对象,那么程序就会crash。如果释放之后把它的指针置为空,则即便后面的程序用到该对象,也不会崩溃。如果没有release就直接把对象置为nil,retaincount等于0,会发生内存泄露。

类的成员变量,定义属性为retain,之后给此成员变量赋值的时候要引用self.调用此变量。但是在alloc的时候不要引用self.来给此变量赋值。

例如:self.m_strTest = [[NSString alloc]init];是错误的。正确的应该是m_strTest = [[NSString alloc]init];

用类方法初始化一个对象时,对象的retaincount是1.

比如

searchButton = [UIButtonbuttonWithType:UIButtonTypeCustom];

此时searchButton的retaincount是1,但是不用自己release。


当你往数组里面添加一个对象时。数组里面存储的并不是这个对象的拷贝,而只是一个指向该对象的指针。数组在保存 这个指针的同时会向指针所指的对象发送一个retain消息,相应的,对象的持有计数会增加。将对象从数组中移除的时候,同样会向对象发送release 消息,对象的持有计数会减小。当我们释放这个数组时,会向保存在这个数组中的所有对象发送release消息。看下面的两个例子:

1、没有释放内存的版本
array = [[NSMutableArray alloc] init];
for ( i = 0; i < 10; i++) {
newNumber = [[NSNumber alloc]initWithInt:(i * 3)];
[array addObject:newNumber];
}

上面的代码在创建newNumber对象时,向对象的发送了retain消息,对象的持有计数变为1。当向array中添加这个对象的引用时,又向对象发送 了一次retain消息,这样对象的持有计数就变为2了,在使用完array时,我们会习惯性的释放掉array,但这样并不会释放array所持有的对 象,而只是使所有对象的持有计数变为1,这些对象依然会占用着内存。

2、释放内存的版本
for (i = 0; i < 10; i++) {
newNumber = [[NSNumber alloc]initWithInt:(i*3)];
[array addObject:newNumber];
[newNumber release];
}


NSString* test = [[NSStringalloc]initWithFormat:@"%@",@"hello"];

    NSLog(@"after alloc=%d",[testretainCount]);//1

    [test retain ];//2

    NSString* test2 = test;

    [test2 retain];

   NSLog(@"after retain=%d",[test retainCount]);//3

    NSMutableArray* array = [[NSMutableArrayalloc]init];

    [array addObject:test];

    NSLog(@"after retain=%d",[testretainCount]);//4

   [array removeObjectAtIndex:0];

   NSLog(@"after array removeObjectAtIndex=%d",[test retainCount]);//5

   // [array removeAllObjects];

    //NSLog(@"after array removeAllObjects=%d",[testretainCount]);//5

    if (1==[test retainCount]) //release和nil应该这样写,这样就会防止乱用nil发生内存泄露,也会防止release之后再实用此对象发生crash

    {

        [test release];

        test= nil;

    }

    else

    {

        [test release];        

    }

    

    if (test)

    {

        NSLog(test);

    }

    NSString* test = [[NSStringalloc]initWithFormat:@"%@",@"hi"];

    [test release];

    [test release];//出错(message sent to deallocated instance),因为test已经被release了.


原创粉丝点击