我们在OC中定义变量,可以自己来定义变量的setter方法来设置变量值,用getter方法来获取变量值。但是当变量数量增多时,还采用手动添加setter/getter方法来操作变量,就会使得程序代码量大大增加。幸好从OC 2.0开始,我们能让系统自动生成设置变量值的方法或获取变量值的方法,即系统会自动为我们生成setter/getter方法。这中功能减少了代码量,让我们有更多的精力放在程序的业务逻辑上。为了使设置变量值的功能更加完善,OC使用@property来标识属性。例如变量可分为只读变量,那么变量的属性为readonly。其中有些属性比较好区分,但还有一些属性assign、copy等属性却让人有些困惑。

先说说采用@property的语法吧!变量的声明语法为:

@property(attribution)Vartype  Varname;//属性在()里来定义,然后是变量类型、变量名。

OC提供的属性有:

读写属性: (readwrite/readonly)以及(getter=name)、(setter=name)

setter语意:(assign/retain/copy)

原子性: (non)atomic

提醒一下,采用@property与自定义setter和getter方式其实是等价的,但是编译器会优先查找自动的setter/getter方法,如果找不到,就会使用@property对应的属性。例如:

@propert(nonatomic ,copy)NSString *name;

这条语句等价于:

完成setter方法为:

-(void)setName:(NSString*)newName{

if(newName!=name){

[name release];

name=[newName  copy];

}

}

完成getter方法为:

-(NSString*)name{

return name;

}

下面详细来说明这些属性的差异

读写属性中,readwrite可以获取实例变量的值。对于@synthesize,编译器会自动为该变量生成getter和setter方法。而readonly表示只读变量,不能设置实例变量的值,编译器不会为其生成setter方法,因此需要进行初始化。而getter/setter=name,是为(getter)/(setter)方法使用name指定的名称,而不是实例变量名称。

setter语意assign/retain/copy 决定了以何种方式对数据成员赋予新值。对于Objective-C中的一般object,最好使用用retain。一些特别的object(例如:string)使用copy。

而assign关键字代表setter直接赋值,而不是复制或者保留它,更不需要进行引用计数。这种机制非常适合一些基本数据类型,比如NSInteger和CGFloat,或者你并不直接拥有的类型,比如delegates((且一定要用assign,具体原因暂时不知道,读者看到这里可以留言给我,告诉我答案)。

这里声明一下,什么是基本基本类型呢? 基本类型就是gc(gc就是垃圾回收的意思)队形,并且只有基本数据类型是gc对象,其它都是非gc的。比如int,float等基本数据类型。而NSString是非gc类型,所以用assign就不适合,而推荐做法是NSString用copy。而类如NSArray,NSDate等其它objc类型,推荐用retain。

而copy与retain的具体区别为:copy其实是建立了一个相同的对象,而retain只是保存其对象,并且其计数值+1。
例如:一个NSString对象,地址为0×1000,内容为@”string” 
copy到另外一个NSString之后,地址为0×2000,内容相同,新的对象retain为1,旧有对象没有变化 
retain到另外一个NSString之后,地址相同(建立一个指针,指针拷贝),内容当然相同,但是这个新对象的retain值+1,并释放旧的对象。
也就是说,retain是指针拷贝,copy是内容拷贝。 

atomicity的默认值是atomic,读取函数为原子操作。atomic是保证读取变量是线程安全的,即它会保证每次getter和setter的操作都会正确的执行完毕,而不用担心其它线程在你get的时候set,可以说保证了某种程度上的线程安全而nonatomic是不能保证线程安全的。但是nonatomic比atomic速度要快。这也是为什么property基本上都用nonatomic了。 最后加上一句,仅仅靠atomic来保证线程安全是不可能的,要写出线程安全的代码,还是需要有同步和互斥机制

注意:

       1.readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用。

2.默认的property行为有:atomic,assign,readwrite。

如果这样使用:@property  BOOL _flag;//代表这_flag有着atomic,assign,readwrite三种行为。所以我们一定要提防这种默认行为潜在的危险。如:

@property NSMutableArray *photoViews;//此时会有警告出现,因为NSMutableArray是一种obj类型,并且是 NSArray类型,根据前面的分析,最好采用retain。所以默认的assign会带来警告提示。

关于属性方面的知识还可以参考:http://www.cnblogs.com/andyque/archive/2011/08/03/2125728.html

Objective-C中变量采用@property的各个属性值的含义

 

Objective-C中变量采用@property的各个属性值的含义的更多相关文章

  1. 清除bean中所有非基本数据类型的属性值

    利用beanutils清除javabean中所有非基本数据类型的属性值: import com.google.gson.Gson; import lombok.Data; import org.apa ...

  2. Format a Property Value 设置属性值的格式

    In this lesson, you will learn how to set a display format and an edit mask to a business class prop ...

  3. java中两个对象间的属性值复制,比较,转为map方法实现

    package com.franson.study.util; import java.lang.reflect.InvocationTargetException; import java.lang ...

  4. jsp中<c:forEach varStatus="status">的属性值问题

    c:forEach varStatus属性 current当前这次迭代的(集合中的)项 index当前这次迭代从 0 开始的迭代索引 count当前这次迭代从 1 开始的迭代计数 first用来表明当 ...

  5. PHP中使用DOM读取解析XML属性值一例

    先看XML文件结构,与常见的文件略有不同,数据并不是用闭合标签保存的,而是直接保存在属性值中. <?xml version="1.0" encoding="utf- ...

  6. SpringBoot 从application.yml中通过@Value读取不到属性值

    package cn.exrick.xboot.mqtt; import org.eclipse.paho.client.mqttv3.*;import org.eclipse.paho.client ...

  7. html中的meta元素及viewport属性值

    <meta name="viewport" content="width=device-width , initial-scale=1.0, maximum-sca ...

  8. Stringboot中@Autowired加了static就属性值就为null

    //错误 @Autowired private static DepartmentDao departmentDao; @Autowired注入,将bean注入进来 @Autowired通过sprin ...

  9. python小知识-__call__和类装饰器的结合使用,数据描述符__get__\__set__\__delete__(描述符类是Python中一种用于储存类属性值的对象)

    class Decorator(): def __init__(self, f): print('run in init......') self.f = f def __call__(self, a ...

随机推荐

  1. zoj 3537 Cake(区间dp)

    这道题目是经典的凸包的最优三角剖分,不过这个题目给的可能不是凸包,所以要提前判定一下是否为凸包,如果是凸包的话才能继续剖分,dp[i][j]表示已经排好序的凸包上的点i->j上被分割成一个个小三 ...

  2. Python多线程锁

    [Python之旅]第六篇(四):Python多线程锁   python lock 多线程 多线程使用方法 多线程锁 摘要:   在多线程程序执行过程中,为什么需要给一些线程加锁以及如何加锁,下面就来 ...

  3. Interpreter Expression 解释器模式

    简介 Interpreter模式也叫解释器模式,是由GoF提出的23种设计模式中的一种.Interpreter是行为模式之一,它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用 ...

  4. DedeCms autoindex和itemindex使用介绍

    autoindex/itemindex 可以使用 @me+1;实现由指定数字开始,下面为大家详细介绍下具体的两者具体的用法,感兴趣的朋友可以参考下 代码如下: <span style=" ...

  5. java 项目request.getParameter("")接收不到值

    如果发现这个方法 以前能接收到参数,现在不能接收到参数的情况下 很有问题出来tocat 或许jak 的问题上, 换个低版本可能就好了

  6. MemCache缓存和C#自带的Cache缓存

    1.MemCache: //初始化 static SockIOPool _pool; // 创建Memcached private static MemcachedClient Create(stri ...

  7. pod install后出现的错误

    [!] Your Podfile has had smart quotes sanitised. To avoid issues in the future, you should not use T ...

  8. 关于SVD(Singular Value Decomposition)的那些事儿

    SVD简介 SVD不仅是一个数学问题,在机器学习领域,有相当多的应用与奇异值都可以扯上关系,比如做feature reduction的PCA,做数据压缩(以图像压缩为代表)的算法,还有做搜索引擎语义层 ...

  9. 测试stopwatch频率

    测试stopwatch频率 using UnityEngine; using System.Collections; using System.Diagnostics; public class te ...

  10. C++ 实现网络爬虫

    吐槽 前天心血来潮, 把自己面试经历下了下来. 我觉得自己求职一路来比较心酸, 也付出了比一般人更多的汗水. 本以为写出来, 好歹可以作为一篇励志故事. 得到的评论却是, 语言只是一门工具. ||| ...