@property

来源:互联网 发布:淘宝充值平台怎么提现 编辑:程序博客网 时间:2024/06/05 16:44

@dynamic@synthesize的区别


@property有两个对应的词,一个是@synthesize,一个是@dynamic

1

如果@synthesize@dynamic都没写,那么默认的就是@syntheszie var = _var;


2

@synthesize的语义是如果你没有手动实现setter方法和getter方法(方法器),那么编译器会自动为你加上这两个方法。

@dynamic告诉编译器,属性的settergetter方法由用户自己实现,系统不自动生成。



假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定


使用@property配合@synthesize可以让编译器自动实现getter/setter方法,使用的时候也很方便,可以直接使用对象.属性的方法调用;


@dynamic后,可以在存取方法中访问一个私有变量来赋值或取值。而@synthesize则直接用@synthesize var = _var;来让属性和私有变量直接等同起来。这就是二者在书写形式上的差别。


这里提供一种利用消息转发机制来实现@dynamicsettergetter方法。

@interface Book :NSObject

{

 @private

    NSMutableDictionary *_propertiesDict;

}

 

@property (nonatomic,copy) NSString *name;

@property (nonatomic,copy) NSString*author;

@property (nonatomic,copy) NSString*version;

 

@end

2Book.m

#import "Book.h"

 

@implementation Book

@dynamic    name; // 不能写成name = _name;否则编译器马上报错

@dynamic    author;

@synthesizeversion;

 

- (id)init

{

    self = [superinit];

    if(self)

    {

        _propertiesDict = [[NSMutableDictionaryalloc] init];

    }

   

    returnself;

}

 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector

{

    NSString *sel =NSStringFromSelector(selector);

    if ([selrangeOfString:@"set"].location ==0)

    {

        return [NSMethodSignaturesignatureWithObjCTypes:"v@:@"];

    }

    else

    {

        return [NSMethodSignaturesignatureWithObjCTypes:"@@:"];

    }

}

 

- (void)forwardInvocation:(NSInvocation *)invocation

{

    NSString *key =NSStringFromSelector([invocationselector]);

    if ([keyrangeOfString:@"set"].location ==0)

    {

        key= [[key substringWithRange:NSMakeRange(3, [keylength]-4)]lowercaseString];

        NSString *obj;

       [invocation getArgument:&objatIndex:2];

        [_propertiesDictsetObject:obj forKey:key];

    }

    else

    {

        NSString *obj = [_propertiesDictobjectForKey:key];

       [invocation setReturnValue:&obj];

    }

}



1 . 可读性: readonlyreadwrite

@property(readwrite,....) valueType value;

默认:readwrite 。通过加入 readwrite属性你的变量就会有 get  set方法


property(readonly,...) valueType value;

这个属性变量就是表明变量只有可读方法,也就是说,你只能使用它的 get方法。  


2,gettersetter

设置访问方法的名字

默认的gettersetter器的名称是和变量名关联的,一定是setVirableNamevirableName,比如上面的变量agesettersetAgegetterage

可以通过设置@property中的settergetter属性来修改settergetter器的方法名。


3,nonatomic

nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。

atomicnonatomic用来决定编译器生成的gettersetter是否为原子操作。


  atomic

                设置成员变量的@property属性时,默认为atomic,提供多线程安全。

                在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomicsetter函数会变成下面这样:

                        {lock}

                                if (property != newValue) { 

                                        [property release]; 

                                        property = [newValue retain]; 

                                }

                        {unlock}



        nonatomic

        禁止多线程,变量保护,提高性能。

        atomicObjc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

        指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定 nonatomic,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了 nonatomic,那么访问器只是简单地返回这个值。

0 0
原创粉丝点击