声明
在Objective-C中,有两种声明变量的方法,第一种直接声明:
@interface Person : NSObject
{
NSString *name;
NSString *sex;
NSString *age;
Hand *hands[2];
Foot *foots[2];
}
第二种可以使用属性,关键字@property,顾名思义,属性就是将变量看作是类的属性:
@interface Person : NSObject
{
NSString *name;
NSString *sex;
NSString *age;
Hand *hands[2];
Foot *foots[2];
}
@property Foot* leftfoot;
@property Foot* rightfoot;
@property Hand* lefthand;
@property Hand* righthand;
属性与直接声明变量不同的地方在于,如果直接声明,在外面要想访问name,需要设置他的setter,getter方法,不能直接访问。
如果使用属性的方法,可以这样进行访问
Person *person = [Person new];
person.leftfoot = [Foot new];
[person setLeftfoot:[Foot new]];
Foot *foot1 = [person leftfoot];
Foot *foot2 = person.leftfoot;
如果实在类的内部可以像这样访问:
-(void)desc{
[self.leftfoot desc];
[_leftfoot desc];
}
self.leftfoot与_leftfoot的访问效果是一样的。
属性的参数
属性的声明是可以带参数的,如下:
@property (nonatomic,strong) Foot* leftfoot;
nonatomic和strong都是属性的参数,代表参数的一些特性:
atomic和nonatomic
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。
设置成员变量的@property属性时,默认为atomic,提供多线程安全。
nonatomic禁止多线程,变量保护,提高性能。
assign与retain
- 接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。
- 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。总结:上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。
@property (nonatomic,assign) Foot* leftfoot;
@property (nonatomic,retain) Foot* rightfoot;
person.leftfoot = [Foot new];
person.rightfoot = [Foot new];
Foot *foot1 = person.leftfoot;
Foot *foot2 = person.rightfoot;
这是对于leftfoot,编译器就会爆出warning:
/Users/umeng/iosdev/Foundation/Foundation/main.m:17:25: Assigning retained object to unsafe property; object will be released after assignment
copy与retain
关于copy与retain,其实都会在赋值的时候,先释放,但是一个是执行copy,一个是执行retain,这里举个例子,可能大家就明白了:
@property (nonatomic,copy) NSString* test;
@property (nonatomic,retain) NSString* test2;
然后进行赋值:
NSMutableString *s = [[NSMutableString alloc]initWithString:@"hello"];
Person *person = [Person new];
person.test =s;
person.test2 =s ;
[s appendString:@" world"];
NSLog(@"%@:%@",person.test,person.test2);
结果:
Paste_Image.pngweak与strong
weak 和 strong 属性只有在你打开ARC时才会被要求使用,这时你是不能使用retain release autorelease 操作的,因为ARC会自动为你做好这些操作,但是你需要在对象属性上使用weak 和strong,其中strong就相当于retain属性,而weak相当于assign。
readwrite与readonly
readwrite 是可读可写特性;需要生成getter方法和setter方法时使用。
readonly 是只读特性 ,只会生成getter方法,不会生成setter方法 ;不希望属性在类外改变。
对比代码效果更好一些,我将代码放在了github上:
https://github.com/mymdeep/OC_foundation
*更多的开发知识,可以关注我的公众号:
网友评论