您的位置:首页 > 其它

OC - Menory(High)

2015-08-14 20:20 344 查看
<main.m>
#import <Foundation/Foundation.h>
#import "Person.h"
#import "OurClass.h"
#import "Student.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {

//        //创建 OurClass 和 Person 对象
//        OurClass *myClass = [[OurClass alloc] init];
//        Person   *per = [[Person alloc] initWithName:@"蒙多" sex:@"男" age:20];
//
//        myClass.person = per;  //相当于myClass.person = [per copy];  当属性为 retain 时,相当于myClass.person = [per retain];  当属性为assign时,相当于直接赋值;
//        NSLog(@"%lu",[per retainCount]);
//
////        [per release];
//        // 属性是 assign 时: 当 per释放后,myClass.person是直接赋值的,所以此时它会变成野指针.这就是为何当实例变量是对象的时候为什么不用 assign 的原因.
//        // 属性是 copy 时: 当 per释放后,myClass.person是新的对象,所以当销毁之前对象时,此时不会影响
//        // 属性是 retain 时: 当 per释放后,myClass.person是持有那个对象的一个所有权,所以当销毁之前对象时,此时不会影响
//
//
//
//
//
////便利构造器
//
//        Person *per1 = [Person personWithName:@"lisi " sex:@"mele" age:22];
//        //便利构造器中放置 autorelease 结束后自动释放
//        NSLog(@"%lu",[per1 retainCount]);
//
//
//
////  集合的内存管理
//
//        Person *per2 = [Person personWithName:@"lvsheng" sex:@"male" age:15];
//        NSLog(@"%lu",[per2 retainCount]);
//
//   /*
//        1.集合会自己管理自己的元素对象,不需要我们管理.
//        2.集合添加元素 会对该对象进行引用计数 + 1 (相当于retain一次)
//        3.集合移除元素 会对该对象进行引用计数 - 1 (相当于release一次)
//
//   */
//
//        //创建数组对象
//        NSMutableArray *arr = [[NSMutableArray alloc]init];
//
//        //数组添加元素  会对该对象进行引用计数 + 1 (相当于retain一次)
//        [arr addObject:per2];
//         NSLog(@"%lu",[per2 retainCount]);
//
//        //数组移除元素  会对该对象进行引用计数 - 1 (相当于release一次)
//        [arr removeObject:per2];
//         NSLog(@"%lu",[per2 retainCount]);
//
//
//        //创建字典
//        NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
//
//        //字典添加元素 会对该对象进行引用计数 + 1 (相当于retain一次)
//        [dic setValue:per2 forKey:@"person"];
//        NSLog(@"%lu",[per2 retainCount]);
//
//
//        //创建集合
//        NSMutableSet *set = [[NSMutableSet alloc] init];
//
//        //集合添加元素 会对该对象进行引用计数 + 1 (相当于retain一次)
//        [set addObject:per2];
//        NSLog(@"%lu",[per2 retainCount]);
//

//集合 copy 问题

//可以理解为集合的 copy 都是 assign 的直接赋值的

Person *per = [[Person alloc] init];   //0~1
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:per];   //1~2

NSMutableArray *arr1 = [arr copy];  //2~3
NSLog(@"%lu",[per retainCount]);

Person *per1 = arr[0];
Person *per2 = arr1[0];
//打印出来地址相同,所以证明可变数组的 copy 是浅拷贝
NSLog(@"%p,%p",per1,per2);

NSArray *array = [[NSArray alloc] initWithObjects:per, nil];
NSLog(@"%lu",[per retainCount]);  //3~4

NSArray *array1 = [array copy];
NSLog(@"%lu",[per retainCount]);  // 4
//地址相同,不可变数组 copy 也使浅拷贝
NSLog(@"%p,%p",array[0],array1[0]);

//多态
//父类指针可以指向子类对象,可以写出我们通用的代码 addSubView:(UIView *)view 方法,需要传入的参数可以是 UIView 对象以及 UIView 子类对象

Person *per_1 = [[Student alloc] init];

}
return 0;
}


<OurClass.h>

#import <Foundation/Foundation.h>
#import "Person.h"

@interface OurClass : NSObject
{
Person *_person;
}

//@property (nonatomic,assign)Person *person;
//@property (nonatomic,copy)Person *person;
@property (nonatomic,retain)Person *person;

@end


<OurClass.m>

#import "OurClass.h"

@implementation OurClass

/*
//assign
-(void)setPerson:(Person *)person
{
_person = person;
}

-(Person *)person
{
return _person;
}

*/

/*
//copy
-(void)setPerson:(Person *)person

{  //判断当前传入的对象是否是已经持有的对象
if (_person != person) {
//释放之前的所有权
[_person release];
//操作 copy 对新的对象持有所有权
_person = [person copy];
}
}
*/

//retain
-(void)setPerson:(Person *)person

{  //判断当前传入的对象是否是已经持有的对象
if (_person != person) {
//释放之前的所有权
[_person release];
//操作 retain ,获取新的持有所有权
_person = [person retain];
}
}

//dealloc
-(void)dealloc
{
//在当前对象销毁时,释放自身实例变量持有的对象所有权
//    [_person release];
//    _person = nil;
self.person = nil;  //此一步代替上面两步
NSLog(@"OurClass 类的对象被销毁了");
[super dealloc];//销毁时

}

@end


<Person.h>

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCopying>
{
NSString *_name;
NSString *_sex;
NSInteger _age;
}

@property (nonatomic,copy)NSString *name;
@property (nonatomic,retain)NSString *sex;  //如果不怕其自身别修改的话,可以用 retain
@property (nonatomic)NSInteger age;

-(id)initWithName:(NSString *)name
sex:(NSString *)sex
age:(NSInteger)age;

+(Person *)personWithName:(NSString *)name
sex:(NSString *)sex
age:(NSInteger)age;

-(void)dealloc;

@end


<Person.m>

#import "Person.h"

@implementation Person

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

+(Person *)personWithName:(NSString *)name
sex:(NSString *)sex
age:(NSInteger)age
{
//对于遍历构造器内部 我们不进行内存管理,会造成内存泄露,如果 release 了,又会野指针问题,所以我们使用 autorelease, 最佳方案
return [[[Person alloc] initWithName:name sex:sex age:age] autorelease];
}

//assign
-(void)setAge:(NSInteger)age
{
_age = age;
}

//retain
-(void)setSex:(NSString *)sex
{
if (_sex != sex) {
[_sex release];
_sex = [sex retain];
}
}

//copy
-(void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name copy];
}
}

-(id)copyWithZone:(NSZone *)zone
{
Person *temp = [[Person alloc] init];
temp.name = self.name;
temp.sex =self.sex;
temp.age = self.age;
return temp;
}

-(void)dealloc
{
//释放自身实例变量持有权,再释放父类的
self.name = nil;
self.sex = nil;
NSLog(@"Person类的对象被销毁了");
[super dealloc];
}

@end


<Student.h>

#import "Person.h"

@interface Student : Person
{
NSNumber *_number;
}

@property (nonatomic,retain)NSNumber *number;

-(id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number;

+(Student *)studentWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number;

-(void)dealloc;

@end


<Student.m>

#import "Student.h"

@implementation Student

-(id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number
{
if ([super initWithName:name sex:sex age:age]) {
_number = number;
}return self;
}

+(Student *)studentWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number
{
return [[[Student alloc] initWithName:name sex:sex age:age munber:number] autorelease];
}

-(void)setNumber:(NSNumber *)number
{
if (_number != number) {
[_number release];
_number = [number retain];
}
}

-(NSNumber *)number
{
return _number;
}

-(void)dealloc
{
self.number = nil;
NSLog(@"Student 类的对象被销毁了");
[super dealloc];
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: