------- <a href="http://www.itheima.com" target="blank">Windows Phone 7手机开发</a>、<a href="http://www.itheima.com" target="blank">.Ios培训</a>、期待与您交流! -------
在前面写的博客中也写到过@property,但是那时候写的是最简单的一种形式,也就是说当我们给一个非oc对象设计setter与getter方法,例如给基本数据类型int、double、enum、struct设置setter与getter方法。可以写成@property int age。但是今天这篇博客,主要想写一些关于给oc对象设置setter与getter方法时如何写@property以及@property中的一些参数。
在写@propety之前,我们先得明白哪些是oc对象哪些是非oc对象。一般来说基本数据类型,例如int、double、char、enum、struct等是非oc对象。一般使用组合关系的,例如Car *_car,这个对象放在某个类中,那么这个*_car是属于oc对象。注意NSString *_name,也是属于oc对象。知道这个后,我们可以开始写@property了。
例如:
main函数:
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Pen.h"
int main()
{
Student *s = [[Student alloc] init]; // s = 1
s.age = 21;
Pen *p = [[Pen alloc] init]; // p = 1
s.pen = p; // p = 2
s.rich = YES;
s.name = @"Twh"; // 此处没有用alloc方法,所以s内部的计数器仍旧保持上一次的值,为1
NSLog(@"s内部计数器的值为:%ld",[s retainCount]); // 检测上一句是否改变了计数器的值
[p release]; // p = 1
[s release]; // s = 0,人对象被回收,那么调用- dealloc方法,使 p = 0,则pen对象被回收
return 0;
}
#import <Foundation/Foundation.h>
#import "Pen.h"
@interface Student : NSObject
{
// 成员变量在此处声明后,默认为protected类型,该类与子类都可以直接访问。oc对象需要内存管理代码,而非oc对象不需要
int _age; // 非oc对象
NSString *_name; // oc对象
Pen *_pen; // oc对象
BOOL _rich; // 非oc对象
}
@property (nonatomic,assign,readwrite) int age;
@property (nonatomic,retain,readwrite) NSString *name;
@property (nonatomic,assign,readwrite,getter = isRich) BOOL rich;
// @property (nonatomic,retain,readwrite) Pen *pen; // 这条语句的详细写法的声明如下:
- (void)setPen:(Pen *)pen;
- (Pen *)pen;
@end
#import "Student.h"
@implementation Student
// @property (nonatomic,retain,readwrite) Pen *pen; 这条语句详细写法的的实现如下:
- (void)setPen:(Pen *)pen
{
if (_pen != pen) // 判断新对象是否等于就对象,是为了防止重复赋值,带来的内存泄露问题
{
[_pen release];
_pen = [pen retain];
}
}
- (Pen *)pen
{
return _pen;
}
- (void)dealloc
{
NSLog(@"年龄为%d岁的Student对象被回收",[self age]); // 打印,用于检测是否调用了- dealloc方法
[_name release]; // 所有的该类拥有的oc对象都需要在- dealloc方法里面释放一次
[_pen release];
[super dealloc]; // - dealloc方法中,必须在最后调用父类的dealloc方法
}
@end
Pen类的声明与实现:
#import <Foundation/Foundation.h>
@interface Pen : NSObject
@end
#import "Pen.h"
@implementation Pen
- (void)dealloc
{
NSLog(@"Pen对象被回收");
[super dealloc];
}
运行的结果为:
@property参数总结:
一、内存管理相关的参数
retain : release使旧值计数器减1,retain使新值计数器加1
assign :直接赋值(这是默认的,适用于非oc对象类型,例如基本数据类型,枚举、结构体也属于基本数据类型)
copy : release使旧值计数器减1,copy使新值计数器加1
上面这三个参数只能写一个,不能写成(retain,copy);
二、是否要生成set方法
readwrite:同时生成setter与getter的声明和实现(这个是默认)
readonly:只会生成getter的声明、实现
注意:setter方法为可读可写方法,getter方法为只读方法 ,读(文件->内存)写(内存—>文件)
三、多线程管理
nonatomic :性能高,(一般写代码时,都需要加上这个)
atomic : 性能低(默认的)
四、setter和getter方法的名称(无所谓的默认值,可写可不写)
setter : 决定了setter方法的名称,一定要有个冒号:
getter : 决定了getter方法的名称(一般用在BOOL类型,将BOOL类型的getter方法改为isxx)