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

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"];

per1per2所指向的空的引用数都1,

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

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

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

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

(1),[per1release];

        [per2release];

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

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

        per1per2所指向的空的引用数都1, array所指向的空的引用为1,

NSLog(@"%@",array);  出数中的内容

        [per1release];

        [per2release];

per1per2的空都被回收,统识别到他的引用数都0

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

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

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

(2),[array release];

array所指向的空被系回收

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

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

per1per2所指向的空的引用数都1,

        NSLog(@"%@",array);若再操作系crash, 被回收, 如果出相当于被回收的数组进行操作,是野指针问题

 [per1release];

[per2release];

per1per2的空都被回收,统识别到他的引用数都0

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

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


(3),  [per1release];

        [per2release];

per1per2所指向的空的引用数都1, array所指向的空的引用为1,

        [arrayrelease];

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