创建者自己释放自己创建的对象,retain alloc new copy都要release 谁想拥有谁做retain。
重复release一个已经释放的对象,会发生野指针错误
Student *stu=[[Studentalloc]init]; //第一步 [stu release]; //第二步 [stu release]; //野指针错误(exc bad access) stu=niu; //清空指针变成空指针 //第三步 [niu release]; //空指针不会报错 |
如上图所示,当指针等于niu的时候,指针和对象的引用被彻底释放,因为指针存储的内存地址为空。
set方法和内存
创建Person
#import <Foundation/Foundation.h> #import "Book.h" @interface Person : NSObject{ Book * _book; }
@property int age; @property Book *book; -(id)initWithAge:(int)age; -(void)readBook; @end |
#import "Person.h" @implementation Person #pragma mark - 生命周期方法 //分组 //这里是对方法注释分组 #pragma mark 构造方法 //添加方法注释 -(id)initWithAge:(int)age{ if(self=[superinit]){ _age=age; } return self; } #pragma mark 垃圾回收 -(void)dealloc{ [_book release]; //等效self.book=nil; [self setBook:nil]; |
NSLog(@"person%i被回收了",_age);
[super dealloc];
}
//只改变传进来的book对象的计数器,而不改变原来持有的对象的计数器
-(void)setBook:(Book *)book{
if(_book!=book){
[_bookrelease]; //释放旧的
_book=[book retain]; //retian新的对象
}
}
-(Book *)book{
return _book;
}
-(void)readBook{
NSLog(@"读书%f",_book.price);
}
@end
创建Book
#import <Foundation/Foundation.h> @interface Book : NSObject @property float price; -(id)initWithPrice:(float)price; @end |
#import "Book.h" @implementation Book -(id)initWithPrice:(float)price{ if(self=[superinit]){ _price=price; } return self; } -(void)dealloc{ NSLog(@"书本被销毁了-->%f",_price); } @end |
#import <Foundation/Foundation.h> #import "Person.h" #import "Book.h" void setBook(Person *p){ // b1-->1 Book *b1=[[Bookalloc]initWithPrice:35]; // b1-->2 p.book=b1; // b1-->1 [b1 release];
//b2-->1 Book *b2=[[Bookalloc]initWithPrice:4]; //b2-->2 b1-->0 p.book=b2; //这里做了两件事情释放旧的Book对象,持有新的Book对象 //b2-->1 [b2 release]; } void readBook(Person *p){ [p readBook]; } int main(int argc,constchar * argv[]) { @autoreleasepool { //p-->1 book-->0 Person *p=[[Personalloc]initWithAge:45]; //p-->1 b1-->1 b2-->1 setBook(p); //p-->1 b1-->0 b2-->1 readBook(p); NSLog(@"人的计数器是%zi,书的计数器是%zi",[p retainCount],[p.book retainCount]); //调用delloc方法p-->0b1-->0 b2-->0 [p release]; } return 0; } |