10-【掌握】@property参数(一)
@property xcode 4.4 前
@property 帮我们生成 get和set方法的声明 我们自己实现 get和set方法
@property 和 @synthesize 联合
@property xcode 4.4后
@property 增强
@property int age;
1)生成一个_age 2)生成get和set方法的声明 3)生成 get和set方法的实现
@property (......) int age;
(一)验证验证: assign是 直接赋值的?
思路:在MRC模式下调用assign属性的方法,僵尸检测下会不会出错
代码验证:
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
@property(nonatomic,assign) Car *car;
/*
assign 直接赋值
-(void)setCar:(Car *)car{
_car = car;
}
验证: assign
retain release 旧值,retain新值
//什么时候使用retain
//在一个类中有关联其他对象的时候,这个对象的 @property (nonatomic,retain)
//什么时候使用assign
//实例变量是基本数据类型的时候
-(void)setCar:(Car *)car{
if(_car != car){
[_car realase];
_car = [car retain];
}
}
*/
@property(nonatomic,assign) int age;//基本数据变量不受影响
-(void)driver;
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new];
Car *car = [Car new];
[p setCar:car];
[car release]; //@property(nonatomic,assign) Car *car;如果没有retain,则car的所有权是2,release后是1,但实际上是报错了,说明的确是直接赋值,没有retain
//如果报错了 setCar 没有进行 retain
[p driver];
[p release]; } return 0; }
(二)验证验证: retain 不是 直接赋值 ,而是进行了以下操作
-(void)setCar:(Car *)car{ if(_car != car){ [_car realase]; _car = [car retain]; } }
思路:在MRC模式下调用retain属性的方法,僵尸检测下会不会出错
代码验证:
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
@property(nonatomic,retain) Car *car;
retain release 旧值,retain新值
//什么时候使用retain
//在一个类中有关联其他对象的时候,这个对象的 @property (nonatomic,retain)
//什么时候使用assign
//实例变量是基本数据类型的时候,默认就是assign
-(void)setCar:(Car *)car{
if(_car != car){
[_car realase]; //初始的的时候,_car明显是nil(无效指针)
_car = [car retain];
}
}
*/
@property(nonatomic,assign) int age;
-(void)driver;
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new];
Car *car = [Car new];
[p setCar:car]; //说明 set方法的内部 确实用来retain
NSLog(@"car.retainCount = %lu",car.retainCount); // 2
[p driver];
[p setCar:car]; // if(_car != car)
[car release]; //1
[p driver];
[p release];
}
return 0;
}
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] car.retainCount = 2
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] 车在跑
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] 车在跑
进一步验证 车的所有权数在@property (nonatomic,retain) 后在内部是2
思路:重写person的dealloc,delloc里面释放—_car,看一看有没有触发_car的dealloc方法
#import "Person.h"
@implementation Person
- (void)dealloc
{
[_car release];
NSLog(@"Person dealloc ");
[super dealloc];
}
-(void)driver{
[_car run];
}
@end
#import "Car.h"
@implementation Car
- (void)dealloc
{
NSLog(@"car dealloc ");
[super dealloc];
}
-(void)run{
NSLog(@"车在跑");
}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new];
// [p setAge:18];
p.age = 28; //调用set方法
NSLog(@"age = %d",p.age);
Car *car = [Car new];
// p.car = car;
[p setCar:car]; //说明 set方法的内部 确实用来retain
NSLog(@"car.retainCount = %lu",car.retainCount); // 2
[p driver];
[p setCar:car]; // if(_car != car)
[car release]; //1
//如果报错了 setCar 没有进行 retain
[p driver];
[p release];
}
return 0;
}
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] car.retainCount = 2
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] 车在跑
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] 车在跑
23:39:14.877 10-【掌握】@property参数(一)[1419:263531] car dealloc
23:39:14.878 10-【掌握】@property参数(一)[1419:263531] Person dealloc
【总结】上面其实是一个MRC下内存管理的总结而已,随带明白
@property (nonatomic,assign)和@property (nonatomic,retain)的实际含义
说到底就记忆assign直接赋值,是默认值;retain是release旧值,retain新值