iOS-内存管理

//
//  main.m
//  OC - 内存管理
//
//  Created by dllo on 16/2/26.
//  Copyright © 2016年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
      /**创建一个Peron类, 有三个实例变量, 可见度为公有的, setter和getter方法, 自定义初始化方法和遍历构造器. */
        
#if 0
        
        Person *person1 = [[Person alloc]init];
        //对象内存的是地址, 指向栈区内的内容
        person1->_name = @"Tom";
        person1->_sex = @"male";
        person1->_age = 21;
        
        /** 直接显示对象大小需要导入<objc/runtime.h>*/
        NSLog(@"size:%ld",class_getInstanceSize([person1 class]));
        
        NSLog(@"%d: 对象和实例变量的地址", __LINE__);
        NSLog(@"person1 add: %p", person1);
        NSLog(@"person1 name add %p", &person1->_name);
        NSLog(@"person1 sex add %p", &person1->_sex);
        NSLog(@"person1 age add %p", &person1->_age);
        NSLog(@"************");
        NSLog(@"%d: 实例变量是对象类型, 指针内容是一个地址.", __LINE__);
        NSLog(@"person1 name content: %p", person1->_name);
        NSLog(@"Tom add : %p", @"Tom");
        NSLog(@"person1 sex content %p", person1->_sex);
        NSLog(@"Man add : %p", @"male");
        NSLog(@"实例变量不是对象类型");
        NSLog(@"person1 age content: %ld", person1->_age);
        
        /** 使用person1 创建一个新的Person类对象 */
        Person *person2 = person1;
        NSLog(@"%d: person2对象和实例变量的地址", __LINE__);
        NSLog(@"person2 add : %p", person2);
        NSLog(@"person2 name add: %p", &person2->_name);
        NSLog(@"person2 sex add: %p", &person2->_sex);
        NSLog(@"person2 age add: %p", &person2->_age);
        
        NSLog(@"person2 name content: %p", person2->_name);
        NSLog(@"tom add : %p", @"Tom");
        
#pragma mark - alloc 方法
        /**开辟内存空间, 内存空间引用数为1 */
        Person *per = [[Person alloc]init];
        /**retaincount查看对象的引用计数 */
        NSLog(@"per: %ld", [per retainCount]);
        
        Person *per2 = [[Person alloc]initWithName:@"tom" sex:@"male" age:33];
        NSLog(@"per2 : %ld", [per2 retainCount]);
        
        Person *per3 = [Person personWithName:@"mafeng" sex:@"male" age:23];
        NSLog(@"per3 : %ld", [per3 retainCount]);
        
#pragma mark - retain 方法
        /**retain 方法使引用计数加1 */
        [per retain];
        NSLog(@"per count: %ld", [per retainCount]);
        [per retain];
        NSLog(@"per count: %ld", [per retainCount]);
        [per2 retain];
        NSLog(@"per2 count: %ld", [per2 retainCount]);
        
#pragma mark - release 释放方法
        /** release方法使引用计数减一 */
        [per release];
        NSLog(@"per count: %ld", [per retainCount]);
        [per release];
        NSLog(@"per count: %ld", [per retainCount]);
        [per release];
        NSLog(@"per count: %ld", [per retainCount]);  //内部的内存优化, 无需去管
        /** 此时per的引用计数为0, 系统会自动调用的dealloc方法, 释放内存 */
        /** 通过重写父类的的dealloc 方法验证一下, 详见Person.m文件 */
        /** 当引用计数为0时, 系统会释放这块内存 */
        /** 在一段代码中引用计数怎加的次数要和减少的次数相等. */
        /** 当引用计数为0后, 在对这块内存的引用计数进行减一, 会造成内存过度释放 */
        //[per release];
        /** 对它进行操作时会造成野指针现象 */
        per->_name = @"Mike";
        
        Person *per4 = per2;
        NSLog(@"per4: %ld", [per4 retainCount]);
        /** 对象的引用计数为0时, 对象的引用变得无效, 这样的引用通常被称为"dangling pointer"悬挂指针. 
            所以此时给对象发送消息往往会出现意外, 甚至发生崩溃.
            这个时候出现野指针现象,
         
         */
        /** 内存泄露: 引用计数增加的次数要比减少的次数多, 此时造成内存的泄露 */
        /** 重点了解引用计数机制, 当引用计数为0的时候, 系统释放已经开辟的内存, 所以要保证在一段代码中引用计数增加和减少的次数相同 */
#endif
#if 1
#pragma mark - autorelease 方法
        /** autorelease 不是立即对引用计数减一. 当向一个对象发送autorelease消息的时候, 这个对象会被添加到最近的自动释放池中, 当离开这个自动释放池的时候, 就会为这个对象发送release消息, 引用计数减一 */
        Person *per = [[Person alloc]init];
        @autoreleasepool {
            [per retain];
            NSLog(@"person count: %ld", [per retainCount]);
            [per autorelease];
            NSLog(@"person count: %ld", [per retainCount]);
        }
        
        NSLog(@"person count: %ld", [per retainCount]);
        
        
#endif
        
        
        
        
        
        
    }
   
    return 0;
}

Person.m

//
//  Person.m
//  OC - 内存管理
//
//  Created by dllo on 16/2/26.
//  Copyright © 2016年 dllo. All rights reserved.
//

#import "Person.h"

@implementation Person

- (void)setName:(NSString *)name{
    _name = name;
}
- (void)setSex:(NSString *)sex{
    _sex = sex;
}
- (void)setAge:(NSInteger)age{
    _age = age;
}
- (NSString *)name{
    return _name;
}
- (NSString *)sex{
    return _sex;
}
- (NSInteger)age{
    return _age;
}
- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age{
    self = [super init];
    if (self) {
        _name = name;
        _age = age;
        _sex = sex;
    }
    return self;
}

+ (instancetype)personWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age{
    Person *per = [[Person alloc]initWithName:name sex:sex age:age];
    return per;
}

- (void)dealloc
{
    NSLog(@"%s: %d", __func__, __LINE__);
    NSLog(@"%@内存被回收",self);
    [super dealloc];
}
@end

 

posted @ 2016-02-26 15:29  ma_fighting  阅读(212)  评论(0)    收藏  举报
历史天气查