iOSiOS干货#iOS#HeminWon

@property @synthesize @dynamic @

2016-08-23  本文已影响437人  凌巅

@property @synthesize @dynamic @synchronized

当你定义了一系列的变量时,需要写很多的getter和setter方法,而且它们的形式都是差不多的,,所以Xcode提供了@property和@synthesize属性,@property用在 .h 头文件中用作声明,@synthesize、@dynamic用在.m 文件中用于实现。

@property 在头文件中声明getter和setter方法
@synthesize 在实现文件中生成相应的getter和setter方法
@dynamic 告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成。(假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃)

以上为旧版本的Xcode的一些特性。在最新的版本中这些关键字的功能有所不同。
1、如果在头文件中使用了@property关键字,则编译器除了声明变量的getter和setter方法之外,还会增加一个_var的成员变量,并且会在.m文件中实现相应的getter和setter方法(设值和取值方法)。
2、@synthesize这个属性可以不用

在使用oc进行开发时,经常需要对大量的成员变量生成设值方法和取值方法,如果全部手动实现,那么将浪费程序员大量的时间敲写这些重复性的垃圾代码。自从oc2.0开始,可以自动生成设值和取值方法。那就是使用@property属性和@synthesize关键字。关于这两个关键字使用中的细节在这里进行详细的解释。

1. 使用@property自动生成成员变量以及取值和设值方法

代码如下:

@interface Person:NSObject 
@property int age; 
@end 
@implementation Person 
@end

解释:例如这种在实现部分不使用@synthesize,直接使用@property属性进行声明,那么编译器会自动生成一个int _age;型的成员变量,而且会在实现部分自动生成如下的设值和取值方法。

- (void)setAge:(int)age 
    { _age = age; } 
- (int)age 
    { return _age; }

2. 手动实现设值方法,使用@property自动生成成员变量和取值方法

代码如下:

@interface Person:NSObject 
@property int age;
 - (void)setAge:(int)age; 
@end 
@implementation Person 
- (void)setAge:(int)age 
    { _age = age; } 
@end

解释:例如这种在实现部分不使用@synthesize,直接使用@property属性进行声明,并且实现部分手动生成了设值setAge:方法,那么编译器会自动生成一个int _age;型的成员变量,而且会在实现部分自动生成如下的取值方法。

- (int)age { return _age; }  

同理,在实现部分不使用@synthesize,直接使用@property属性进行声明,并且实现部分手动生成了取值age:方法,那么编译器会自动生成一个int _age;型的成员变量,而且会在实现部分自动生成setAge:的设值方法。

3. 手动实现设值和取值方法,使用@property不会自动生成成员变量

代码如下:

@interface Person:NSObject 
{ int _age; //此处必须手动实现 } 
@property int age; 
- (void)setAge:(int)age; 
- (int)age; 
@end
@implementation Person 
- (void)setAge:(int)age { _age = age; } 
- (int)age { return _age; } 
@end

解释:例如这种手动实现设值和取值方法,那么即使使用了@property属性,那么编译器也不会自动生成一个int _age型的成员变量,必须自己手动声明一个_age的成员变量。如果不手动声明,那么编译器就会报错,因为设值和取值方法找不到_age的成员变量。

4. @synthesize的使用

代码如下:

@interface Person:NSObject 
{     int _age; 
    int age; 
} 
@property int age; 
@end 
@implementation Person 
@synthesize age; 
@end

解释:
这种使用了@synthesize age;的情况,那么设置和取值方法会默认访问age成员变量,而不是_age成员变量,如果没有声明age的成员变量,那么设置和取值方法才会访问_age的成员变量。
如果想让设置和取值方法访问_age的成员变量,那么必须显示指明,即使用@synthesize age=_age,这样设置和取值方法就会访问_age的成员变量,而不是age的成员变量。
例如@synthesize age=_age这种显示指明访问哪个成员变量的方式,如果没有声明_age的成员变量而声明了age的成员变量,那么编译器也不会访问age成员变量,编译器而是会自动生成一个_age的成员变量去访问。

总结
@property和@synthesize提高了开发者的效率,不用重复的去敲写垃圾代码。
在使用了@property的情况,若手动实现了设值方法,编译会自动生成取值方法;若手动实现了取值方法,编译会自动生成设置值法(若只手动实现其中一个,编译器还会自动生成相应的成员变量);若手动实现了设值和取值方法,编译不会自动生成不存在的成员变量。
@synthesize age=variablename,age是属性, variablename才是我们要访问的成员变量。

@synchronized 锁

@synchronized,代表这个方法加锁, 相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程例如B正在用这个方法,有的话要等正在使用synchronized方法的线程B运行完这个方法后再运行此线程A,没有的话,直接运行。
代码如下:

//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    @synchronized(obj){
        [obj method1];
        sleep(10);
    }
});

//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    sleep(1);
    @synchronized(obj){
        [obj method2];
    }
});
上一篇下一篇

猜你喜欢

热点阅读