属性与内存管理(属性与内存管理都是相互关联的)第二部分-创新互联

四,关于语义特性copy和与alloc对应的dealloc以及初始化操作和便利构造器的补充

创新互联建站成都网站建设按需网站开发,是成都网站营销推广公司,为成都服务器托管提供网站建设服务,有成熟的网站定制合作流程,提供网站定制设计服务:原型图制作、网站创意设计、前端HTML5制作、后台程序开发等。成都网站推广热线:18982081108

1, 语义特性copy

如果想对一个对象进行copy操作,对象的类必须服从一个NSCopying协议,并且实现协议中的方法copyWithZone:,方法为(仍以Person类为例):

-(id)copyWithZone:(NSZone*)zone

{

   NSString*newSex = [[NSStringallocWithZone:zone]init];

   newSex.sex = self.sex;

   returnnewSex;

}

其中copyWithZone: 是协议NSCopying制定的方法,

2, dealloc

对于dealloc方法,由于系统不知道我们在开发程序时会对那些对象的语义特性声明为retain或者copy,所以需要我们重写dealloc方法,即如下:

-(void)dealloc

{

 [_namerelease];

 [_sexrelease];

 NSLog(@"Person空间回收了");

 [superdealloc];

}

(1), [_namerelease]和[_sexrelease]操作目的:当调用dealloc方法时,该对象的空间将要被系统回收,在空间回收之前,将保有的其他对象()的所有权给释放掉,当该类对象的引用计数为0时,会自动调用该类的dealloc方法

(2), [superdealloc]该操作即必须通过super调用父类的方法实现,才能将空间回收,

3, 初始化操作

-(id)initWithName:(NSString*)name sex:(NSString *)sex

{

   self =[superinit];

   if (self) {

       self.name = name;

       self.sex = sex;

   }

   returnself;

}

(1),使用self.name = name赋值方法,self.name时调用了setter方法,内部对name进行了retain操作,即_name也保留了name的使用权,如果使用_name = name即直接赋值方法,则就表示把属性的语义特性设为asgin,这时如果name的空间已经被回收了,直接赋值就会出现野指针问题

使用self.sex = sex同理;

(4),便利构造器

+(id)teacherWithName:(NSString*)name sex:(NSString *)sex

{

 Person*person = [[Person alloc] initWithName:namesex:sex];

   return [Personautorelease];

}

我们在使用便利构造器时不需要再对其进行release操作,因为内部已经做了autorelease操作,如果在进行release操作会造成过度释放,以后我们再写便利构造器就要这样写.

五,collection(集合) 的内存管理

当把一个对象放入集合(数组,字典,集合)中时,会将对象的引用计数 + 1,因为内部做了retain操作

例如: Person *per1 = [[Personalloc] initWithName:@"Frank"sex:@"boy"];

       Person *per2= [[Personalloc] initWithName:@"Duke"sex:@"boy"];

此时per1和per2所指向的空间的引用计数都为1,

NSMutableArray *array =[[NSMutableArray alloc ]initWithObjects:per1,per2, nil];

 这里使用便利构造器,其内部给添加到数组中的元素进行了autorelease操作,这时per1和per2所指向的空间的引用计数都为2,

当集合(数组,字典,集合)空间被回收时,他们会向容器中的每个元素发送一个release消息(对应添加元素时的retain操作),当从集合(数组,字典,集合)中移除一个元素时,会release该对象,引用计数 - 1;

下面把对该数组对象以及存储的对象的进行release操作

(1),[per1release];

       [per2release];

       NSLog(@"%lu",[ per1retainCount]);

       NSLog(@"%lu",[ per2retainCount]);

       此时 per1和per2所指向的空间的引用计数都为1, array所指向的空间的引用计数为1,

NSLog(@"%@",array); 此时会输出数组中的内容

       [per1release];

       [per2release];

此时per1和per2的空间都被回收,因为系统识别到他们的引用计数都为0

       NSLog(@"%@",array);此时若再执行该操作系统会crash,因为数组中存储的对象已经被系统回收了,如果输出相当于又对数组中被回收的空间进行操作,是野指针问题

NSLog(@"arrayCount= %lu",[array retainCount]);

此时array所指向的空间的引用计数为1,因为array的空间没有被回收,但不可以输出数组

(2),[array release];

此时array所指向的空间被系统回收

       NSLog(@"%lu",[tea1retainCount]);

       NSLog(@"%lu",[tea2retainCount]);

此时per1和per2所指向的空间的引用计数都为1,

       NSLog(@"%@",array);此时若再执行该操作系统会crash, 因为数组已经被回收, 如果输出相当于对被回收的数组进行操作,是野指针问题

 [per1release];

[per2release];

此时per1和per2的空间都被回收,因为系统识别到他们的引用计数都为0

NSLog(@"arrayCount= %lu",[array retainCount]);

若进行此操作,会crash, 因为array的空间已经被回收

(3), [per1release];

       [per2release];

此时per1和per2所指向的空间的引用计数都为1, array所指向的空间的引用计数为1,

       [arrayrelease];

此时array所指向的空间被系统回收,per1和per2的空间也都被回收,当集合(数组,字典,集合)空间被回收时,他们会向容器中的每个元素发送一个release消息(对应添加元素时的retain操作),即此时per1和per2的空间都被回收,因为他们收到了release消息,

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前名称:属性与内存管理(属性与内存管理都是相互关联的)第二部分-创新互联
本文地址:http://azwzsj.com/article/dggocj.html