OC内存分析之retain与copy的简单测试示例
2016-03-18 16:19
302 查看
OC内存分析之retain与copy的简单测试示例
1、初始化Circle类的origin时可以采用以下方式:
(1)origin = [[XYPoint alloc] initWithX:_p.x andY:_p.y];
(2)origin = [_p retain];
或 origin = [_p copy];//此时,XYPoint类需要“遵循”NSCopying协议并实现协议的copyWithZone:方法,以实现深拷贝。
- (id)copyWithZone: (NSZone *)zone
{//拷贝 用已经存在的对象实例化新对象 origin=[_p copy];
XYPoint* temp = [[XYPoint alloc] initWithX:x andY:y];
return temp;
}
(3)self.origin = _p;//等价于[self setOrigin:_p];
内存分析方式取决于setOrigin:内部的实现
.如果声明属性时,赋值方式为 assign,setOrigin:内部的实现如下:
-(void)setOrigin:(XYPoint*)_p
{
origin = _p;
}
.如果声明属性时,赋值方式为 retain,setOrigin:内部的实现如下:
-(void)setOrigin:(XYPoint*)_p
{
if(origin != _p)
{
[origin release];
origin = [_p retain];
}
}
.如果声明属性时,赋值方式为 copy,setOrigin:内部的实现如下:
-(void)setOrigin:(XYPoint*)_p
{
[origin release];
origin = [_p copy];
}
eg:
XYPoint.h
#import <Foundation/Foundation.h>
//类“遵循”协议,那么类中必须要实现协议中的@required方法
//@optional
//copy 消息的接收者所属类需要“遵循”NSCopying协议,并实现协议中的copyWithZone:方法。
@interface XYPoint : NSObject<NSCopying>{
int x;
int y;
}
@property(nonatomic,assign)int x;
@property(nonatomic,assign)int y;
-(id)initWithX:(int)_x andY:(int)_y;
-(NSString*)description;
@end
XYPoint.m
#import "XYPoint.h"
@implementation XYPoint
@synthesize x,y;
-(id)initWithX:(int)_x andY:(int)_y
{
if (self = [super init]) {
x = _x;
y = _y;
}
return self;
}
//对象名.成员函数 [对象 消息];
- (id)copyWithZone:(NSZone *)zone
{//拷贝 用已经存在的对象实例化新对象 origin=[_p copy];
XYPoint* temp = [[XYPoint alloc] initWithX:x andY:y];
return temp;
}
-(NSString*)description
{
return [NSString stringWithFormat%@“(%d,%d)”,x,y];
}
@end
Circle.h
#import <Foundation/Foundation.h>
#import "XYPoint.h"
@interface Circle : NSObject{
int radius;
XYPoint* origin;
}
@property(nonatomic,assign)int radius;
@property(nonatomic,retain)XYPoint* origin;
-(id)initWithR:(int)_r andOrigin:(XYPoint*)_p;
-(NSString*)description;
@end
Circle.m
#import "Circle.h"
@implementation Circle
@synthesize radius,origin;
//
-(id)initWithR:(int)_r andOrigin:(XYPoint*)_p
{
if(self = [super init])
{
radius = _r;
// origin = [[XYPoint alloc] initWithX:_p.x andY:_p.y];//常规做法
// origin = _p;//有没有问题?有 二次删除问题
//origin = [_p retain];//修改之后的语句
origin = [_p copy];//执行过程与内存分析
// self.origin = _p;
// self.origin = [[[XYPoint alloc] init] autorelease];
}
return self;
}
-(NSString*)description
{
return [NSString stringWithFormat%@“r:%d,origin:%@",radius,origin];
}
-(void)dealloc
{//如果类中有对象实例变量,为了避免内存泄漏,可以重写dealloc
[origin release];//nil:空对象 Nil
//向空对象发送消息没有效果
[super dealloc];
}
@end
main.m(测试retain)
#import <Foundation/Foundation.h>
#import "Circle.h"
#import "XYPoint.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//个数一致 alloc+retain+copy ==release+autorelease
XYPoint* p = [[XYPoint alloc] initWithX:1 andY:1];//p引用计数为1
Circle* c = [[Circle alloc] initWithR:1 andOrigin:p];//c引用计数为1
//测试retain
XYPoint* p1 = [p retain];//p与p1指向同一块堆空间,并且引用计数会加1 p引用计数为2
NSLog(@"%lu,%lu",[p retainCount],[p1 retainCount]);
[p release];
[c release];
}
return 0;
}
输出结果2,2
main.m(测试copy)
#import <Foundation/Foundation.h>
#import "Circle.h"
#import "XYPoint.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
XYPoint* p = [[XYPoint alloc] initWithX:1 andY:1];//p引用计数为1
Circle* c = [[Circle alloc] initWithR:1 andOrigin:p];//c引用计数为1
//测试copy
XYPoint* p1 = [p copy];//深拷贝 p与p1引用计数都为1,各自指向一块堆空间
NSLog(@"%lu,%lu",[p retainCount],[p1 retainCount]);
[p release];
[c release];
}
return 0;
}
输出结果为:1,1
1、初始化Circle类的origin时可以采用以下方式:
(1)origin = [[XYPoint alloc] initWithX:_p.x andY:_p.y];
(2)origin = [_p retain];
或 origin = [_p copy];//此时,XYPoint类需要“遵循”NSCopying协议并实现协议的copyWithZone:方法,以实现深拷贝。
- (id)copyWithZone: (NSZone *)zone
{//拷贝 用已经存在的对象实例化新对象 origin=[_p copy];
XYPoint* temp = [[XYPoint alloc] initWithX:x andY:y];
return temp;
}
(3)self.origin = _p;//等价于[self setOrigin:_p];
内存分析方式取决于setOrigin:内部的实现
.如果声明属性时,赋值方式为 assign,setOrigin:内部的实现如下:
-(void)setOrigin:(XYPoint*)_p
{
origin = _p;
}
.如果声明属性时,赋值方式为 retain,setOrigin:内部的实现如下:
-(void)setOrigin:(XYPoint*)_p
{
if(origin != _p)
{
[origin release];
origin = [_p retain];
}
}
.如果声明属性时,赋值方式为 copy,setOrigin:内部的实现如下:
-(void)setOrigin:(XYPoint*)_p
{
[origin release];
origin = [_p copy];
}
eg:
XYPoint.h
#import <Foundation/Foundation.h>
//类“遵循”协议,那么类中必须要实现协议中的@required方法
//@optional
//copy 消息的接收者所属类需要“遵循”NSCopying协议,并实现协议中的copyWithZone:方法。
@interface XYPoint : NSObject<NSCopying>{
int x;
int y;
}
@property(nonatomic,assign)int x;
@property(nonatomic,assign)int y;
-(id)initWithX:(int)_x andY:(int)_y;
-(NSString*)description;
@end
XYPoint.m
#import "XYPoint.h"
@implementation XYPoint
@synthesize x,y;
-(id)initWithX:(int)_x andY:(int)_y
{
if (self = [super init]) {
x = _x;
y = _y;
}
return self;
}
//对象名.成员函数 [对象 消息];
- (id)copyWithZone:(NSZone *)zone
{//拷贝 用已经存在的对象实例化新对象 origin=[_p copy];
XYPoint* temp = [[XYPoint alloc] initWithX:x andY:y];
return temp;
}
-(NSString*)description
{
return [NSString stringWithFormat%@“(%d,%d)”,x,y];
}
@end
Circle.h
#import <Foundation/Foundation.h>
#import "XYPoint.h"
@interface Circle : NSObject{
int radius;
XYPoint* origin;
}
@property(nonatomic,assign)int radius;
@property(nonatomic,retain)XYPoint* origin;
-(id)initWithR:(int)_r andOrigin:(XYPoint*)_p;
-(NSString*)description;
@end
Circle.m
#import "Circle.h"
@implementation Circle
@synthesize radius,origin;
//
-(id)initWithR:(int)_r andOrigin:(XYPoint*)_p
{
if(self = [super init])
{
radius = _r;
// origin = [[XYPoint alloc] initWithX:_p.x andY:_p.y];//常规做法
// origin = _p;//有没有问题?有 二次删除问题
//origin = [_p retain];//修改之后的语句
origin = [_p copy];//执行过程与内存分析
// self.origin = _p;
// self.origin = [[[XYPoint alloc] init] autorelease];
}
return self;
}
-(NSString*)description
{
return [NSString stringWithFormat%@“r:%d,origin:%@",radius,origin];
}
-(void)dealloc
{//如果类中有对象实例变量,为了避免内存泄漏,可以重写dealloc
[origin release];//nil:空对象 Nil
//向空对象发送消息没有效果
[super dealloc];
}
@end
main.m(测试retain)
#import <Foundation/Foundation.h>
#import "Circle.h"
#import "XYPoint.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//个数一致 alloc+retain+copy ==release+autorelease
XYPoint* p = [[XYPoint alloc] initWithX:1 andY:1];//p引用计数为1
Circle* c = [[Circle alloc] initWithR:1 andOrigin:p];//c引用计数为1
//测试retain
XYPoint* p1 = [p retain];//p与p1指向同一块堆空间,并且引用计数会加1 p引用计数为2
NSLog(@"%lu,%lu",[p retainCount],[p1 retainCount]);
[p release];
[c release];
}
return 0;
}
输出结果2,2
main.m(测试copy)
#import <Foundation/Foundation.h>
#import "Circle.h"
#import "XYPoint.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
XYPoint* p = [[XYPoint alloc] initWithX:1 andY:1];//p引用计数为1
Circle* c = [[Circle alloc] initWithR:1 andOrigin:p];//c引用计数为1
//测试copy
XYPoint* p1 = [p copy];//深拷贝 p与p1引用计数都为1,各自指向一块堆空间
NSLog(@"%lu,%lu",[p retainCount],[p1 retainCount]);
[p release];
[c release];
}
return 0;
}
输出结果为:1,1
相关文章推荐
- Precompiling assets failed.remote
- Gradle sync failed: Unable to start the daemon process
- (算法-training)前缀表达式
- (算法-training)Anagrams问题
- 测试用例设计之二——Pairwise Testing——成对测试
- time_wait和clost_wait说明
- crossdomain.xml跨越
- Skipping failed optional dependency /chokidar/fsevents
- DetailsView设置列隐藏是设置Fields而不是Rows
- 修复.MYI'; try to repair it
- AIDL及IPC浅谈
- LeetCode--Container With Most Water
- 【CodeForces 651B】Beautiful Paintings 排序+贪心
- grails简介
- 人工智能革命:人类将永生或者灭绝
- SSH Secure Shell 无法登录:server responded "algorithm negotiation failed”
- nginx 进程间通信-socketpair
- 遭遇人工智能?莫慌!我们有必杀技
- 响应者链条-(What is responder chain)
- Ibatis中的动态SQL:isNotNull,isPropertyAvailable,isNotEmpty用法