转:http://tigercat1977.blog.163.com/blog/static/2141561122012111293721234/

第四讲:Obj-C 内存管理2 - retain / copy 

主要内容
      retain 属性主要作用
@property (retain) 编译器如何申明
      @synthesize 编译器如何展开实现
      dealloc 需要注意内容

      copy 属性的主要内容

OC 内存管理和点语法
    OC 内存管理正常情况要使用大量的 retain 和 release 操作
    点语法可以减少使用 retain 和 release 的操作

Person.h 头文件申明
      @interface person: NSObject
      {
            Dog * _dog;
      }
      @property (retain) Dog *dog;
      @end

Person.m 实现文件
      @implementation Person
      @synthesize dog = _dog
      - (void) dealloc
      {
           self.dog = nil;
           [super dealloc];
      }


编译器对于 retain 展开形式
      编译器对于 @prooerty 中的 retain 展开是不一样的
      主要是要释放上一次的值,增加本次计数器

@property 展开(retain 属性)

      @property(retain) Dog *dog;
      仍然是展开为:
     - (void) setDog:(Dog *)aDog;
     - (Dog*) dog;

@synthesize ( retain 属性)
      @synthesize dog = _dog;
      展开为:
      - (void) setDog:(Dog*) aDog{
            if (_dog != aDog) {
                 [_dog release];
                 _dog = [aDag retain];
            }
      }
      - (Dog*) dog {
            return _dog;
      }
dealloc 必须要释放 dog (retain)
      - (void) delloc
      {
            self.dog = nil;
            [super dealloc];
      }

copy属性
      copy 属性是完全把对象重新拷贝了一份,计数器从新设置为1, 和之前拷贝的数据完全脱离关系

      @property (copy) NSString* str;
      // 表示属性的 getter 函数
      - (double) str
      {
            return str;
      }
      // 表示属性的 setter 函数
      - (void) setStr:(NSString*) newStr
      {
            str = [newStr copy];
      }

assign ,  retain ,  copy
      foo = value;
     // 简单的引用赋值
      foo = [value retain];
      // 引用赋值,并且增加 value 的计数器
      foo = [value copy];
     // 将 value 复制了一份给 foo, 复制后, foo 和 value 就毫无关系

举例 (把上一讲的改一下,运行结果不变)

// Dog.h #import <Foundation/Foundation.h> @interface Dog : NSObject { int _ID; } @property int ID; @end

// Dog.m #import "Dog.h" @implementation Dog @synthesize ID = _ID; - (void) dealloc { NSLog(@"dog %d is dealloc", _ID); [super dealloc]; } @end


// Person.h #import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject { Dog *_dog; } @property (retain) Dog *dog; /* 被上一行代替 - (void) setDog:(Dog *)aDog; - (Dog *) dog; */ @end

// Person.m #import "Person.h" @implementation Person @synthesize dog = _dog; /* 被上一行代替 - (void) setDog:(Dog *)aDog { if (aDog != _dog) { [_dog release]; _dog = [aDog retain]; // 让计数器 +1 } } - (Dog *) dog { return _dog; } */ - (void) dealloc { NSLog(@"person is delloc"); // 把人拥有的 _dog 释放 // [_dog release] 等于 _dog = nil self.dog = nil; // [self setDog:nil]; 和上边一行相等 [super dealloc]; } @end


//  main.m
#import <Foundation/Foundation.h>
#import "Dog.h"
#import "Person.h"

int main (int argc, const char * argv[])
{
    @autoreleasepool
    {
        Dog *dog1 = [[Dog alloc] init];
        [dog1 setID:1];
        
        Dog *dog2 = [[Dog alloc] init];
        [dog2 setID:2];
        
        Person *xiaoLi = [[Person alloc] init];
        // 小丽要遛狗
        [xiaoLi setDog:dog1];
        [xiaoLi setDog:dog2];
        
        NSLog(@"dog1 retain count is %ld", [dog1 retainCount]);
        //输出:dog1 retain count is 1
        [dog1 release];
        //输出:dog 1 is dealloc
        
        NSLog(@"dog2 retain count is %ld", [dog2 retainCount]);
        //输出:dog2 retain count is 2
        [xiaoLi release];
        //输出:person is delloc
        
        NSLog(@"dog2 retain count is %ld", [dog2 retainCount]);
        //输出:dog2 retain count is 1
        [dog2 release];
        //输出:dog 2 is dealloc
    }
    return 0;
}

(这讲完)

 

posted on 2013-03-07 16:54  jackljf  阅读(157)  评论(0编辑  收藏  举报