新闻资讯
记录首创点滴进步 见证远行
我们一直紧跟时代前沿,聚焦行业实时动态,发布公司最新资讯,欢迎您的关注
您目前的位置:网站首页 > 新闻资讯 > 网站常识 >

5.21日音讯,objective-C-引用计数详解

发布日期:2013-05-21文章来源:首创网络浏览次数:713次
    5.21日音讯,objective-C-引用计数详解。obj-c本质就是改进过的c语言,大家都知道c语言是没有垃圾回收(GC)机制的(注:虽然obj-c2.0后来增加了GC功能,但是在iphone上不能用,因此对于iOS平台的程序员来讲,这个几乎没啥用),所以在......
    本文关键字:5.21日,音讯,objective-C-,引用,计数,详解,5.21
  5.21日音讯,objective-C-引用计数详解。obj-c本质就是"改进过的c语言",大家都知道c语言是没有垃圾回收(GC)机制的(注:虽然obj-c2.0后来增加了GC功能,但是在iphone上不能用,因此对于iOS平台的程序员来讲,这个几乎没啥用),所以在obj-c中写程序时,对于资源的释放得由开发人员手动处理,相对要费心一些。
  引用计数
  这是一种古老但有效的内存管理方式。每个对象(特指:类的实例)内部都有一个retainCount的引用计数,对象刚被创建时,retainCount为1,可以手动调用retain方法使retainCount+1,同样也可以手动调用release方法使retainCount-1,调用release方法时,如果retainCount值减到0,系统将自动调用对象的dealloc方法(类似于c#中的dispose方法),开发人员可以在dealloc中释放或清理资源。
  1、基本用法
  为了演示这种基本方式,先定义一个类Sample
  类接口部分Sample.h
  //
  //Sample.h
  //MemoryManage_1
  //
  //Createdbyjimmy.yangon11-2-19.
  //Copyright2011__MyCompanyName__.Allrightsreserved.
  //
  #import<Foundation/Foundation.h>
  @interfaceSample:NSObject{
  }
  @end
  类实现部分Sample.m
  //
  //Sample.m
  //MemoryManage_1
  //
  //Createdbyjimmy.yangon11-2-19.
  //Copyright2011__MyCompanyName__.Allrightsreserved.
  //
  #import"Sample.h"
  @implementationSample
  -(id)init
  {
  if(self=[superinit]){
  NSLog(@"构造函数被调用了!当前引用计数:%d",[selfretainCount]);
  }
  return(self);
  }
  -(void)dealloc{
  NSLog(@"析构函数将要执行...,当前引用计数:%d",[selfretainCount]);
  [superdealloc];
  }
  @end
  代码很简单,除了"构造函数"跟"析构函数"之外,没有任何其它多余处理。
  主程序调用
  #import<Foundation/Foundation.h>
  #import"Sample.h"
  intmain(intargc,constchar*argv[]){
  Sample*_sample=[Samplenew];//构造函数被调用了!当前引用计数:1
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//1
  [_sampleretain];
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//2
  [_sampleretain];
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//3
  [_samplerelease];
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//2
  [_samplerelease];
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//1
  [_samplerelease];//析构函数将要执行...,当前引用计数:1
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//1,注:即便是在析构函数执行后,如果立即再次引用对象的retainCount,仍然返回1,但以后不管再试图引用该对象的任何属性或方法,都将报错
  NSLog(@"_sample.retainCount=%d",[_sampleretainCount]);//对象被释放之后,如果再尝试引用该对象的任何其它方法,则报错
  //[_sampleretain];//同上,会报错
  return0;
  }
  这段代码主要验证:对象刚创建时retainCount是否为1,以及retain和release是否可以改变retainCount的值,同时retainCount减到0时,是否会自动执行dealloc函数
  nil的问题:
  1.1如果仅声明一个Sample类型的变量(其实就是一个指针),而不实例化,其初始值为nil
  1.2变量实例化以后,就算release掉,dealloc被成功调用,其retainCount并不马上回到0(还能立即调用一次且仅一次[xxxretainCount]),而且指针变量本身也不会自动归为nil值
  1.3dealloc被调用后,必须手动赋值nil,retainCount才会自动归0
  以上结论是实际试验得出来的,见下面的代码:
  Sample*s;
  NSLog(@"s%@,retainCount=%d",s==nil?@"isnil":@"isnotnil",[sretainCount]);//sisnil,retainCount=0
  s=[Samplenew];
  NSLog(@"s%@,retainCount=%d",s==nil?@"isnil":@"isnotnil",[sretainCount]);//sisnotnil,retainCount=1
  [srelease];
  NSLog(@"s%@,retainCount=%d",s==nil?@"isnil":@"isnotnil",[sretainCount]);//sisnotnil,retainCount=1
  //NSLog(@"s%@,retainCount=%d",s==nil?@"isnil":@"isnotnil",[sretainCount]);//报错:Programreceivedsignal:“EXC_BAD_ACCESS”.
  s=nil;
  NSLog(@"s%@,retainCount=%d",s==nil?@"isnil":@"isnotnil",[sretainCount]);//sisnil,retainCount=0
  所以千万别用if(x==nil)或if([xretainCount]==0)来判断对象是否被销毁,除非你每次销毁对象后,手动显式将其赋值为nil
  2、复杂情况
  上面的示例过于简章,只有一个类自己独耍,如果有多个类,且相互之间有联系时,情况要复杂一些。下面我们设计二个类Shoe和Man(即“鞋子类”和”人“),每个人都要穿鞋,所以Man与Shoe之间应该是Man拥有Shoe的关系。
  Shoe.h接口定义部分
  #import<Foundation/Foundation.h>
  @interfaceShoe:NSObject{
  NSString*_shoeColor;
  int_shoeSize;
  }
  //鞋子尺寸
  -(void)setSize:(int)size;
  -(int)Size;
  //鞋子颜色
  -(void)setColor:(NSString*)color;
  -(NSString*)Color;
  //设置鞋子的颜色和尺码
  -(void)setColorAndSize:(NSString*)pColorshoeSize:(int)pSize;
  @end
  Shoe.m实现部分
  //
  //Shoe.m
  //MemoryManage_1
  //
  //Createdbyjimmy.yangon11-2-19.
  //Copyright2011__MyCompanyName__.Allrightsreserved.
  //
  #import"Shoe.h"
  @implementationShoe
  //构造函数
  -(id)init
  {
  if(self=[superinit]){
  _shoeColor=@"black";
  _shoeSize=35;
  }
  NSLog(@"一双%@%d码的鞋子造好了!",_shoeColor,_shoeSize);
  return(self);
  }
  -(void)setColor:(NSString*)newColor
  {
  _shoeColor=newColor;
  }
  -(NSString*)Color
  {
  return_shoeColor;
  }
  -(void)setSize:(int)newSize
  {
  _shoeSize=newSize;
  }
  -(int)Size
  {
  return_shoeSize;
  }
  -(void)setColorAndSize:(NSString*)colorshoeSize:(int)size
  {
  [selfsetColor:color];
  [selfsetSize:size];
  }
  //析构函数
  -(void)dealloc
  {
  NSLog(@"%@%d码的鞋子!",_shoeColor,_shoeSize);
  [superdealloc];
  }
  @end
  Man.h定义部分
  //
  //Man.h
  //MemoryManage_1
  //
  //Createdbyjimmy.yangon11-2-20.
  //Copyright2011__MyCompanyName__.Allrightsreserved.
  //
  #import<Foundation/Foundation.h>
  #import"Shoe.h"
  @interfaceMan:NSObject{
  NSString*_name;
  Shoe*_shoe;
  }
  -(void)setName:(NSString*)name;
  -(NSString*)Name;
  -(void)wearShoe:(Shoe*)shoe;
  @end
  Man.m实现部分
  //
  //Man.m
  //MemoryManage_1
  //
  //Createdbyjimmy.yangon11-2-20.
  //Copyright2011__MyCompanyName__.Allrightsreserved.
  //
  #import"Man.h"
  @implementationMan
  //构造函数
  -(id)init
  {
  if(self=[superinit]){
  _name=@"noname";
  }
  NSLog(@"新人\"%@\"出生了!",_name);
  return(self);
  }
  -(void)setName:(NSString*)newName
  {
  _name=newName;
  }
  -(NSString*)Name
  {
  return_name;
  }
  -(void)wearShoe:(Shoe*)shoe
  {
  _shoe=shoe;
  }
  //析构函数
  -(void)dealloc
  {
  NSLog(@"\"%@\"信息!",_name);
  [superdealloc];
  }
  
    本文由邯郸网络公司首创网络整理编辑发布,请勿转载、复制、摘抄等!

+ 查看更多我们的客户 / Our client

0310-4559740
400-990-1661
    24小时报务热线
    18931045623
在线客服
首创网络邯郸公司
邯郸公司
电话:0310-4559740 / 18931045623  地址:邯郸市丛台区颐高广场B座13层1304室