IOS,objective_C中用@interface和 @property 方式声明变量的区别
转自:http://www.cnblogs.com/letmefly/archive/2012/07/20/2601338.html
一直有疑问,在objective_C中声明变量会有 2种方式,今天有空和网友讨论了下,并且自己查了stackoverflew后算是稍微弄懂了一点。记录如下:
用了一段oc;会发现有2种定义变量的方式
1.在 @interface :NSObject{} 的括号中,当然NSObject 是指一个父类,可以是其他的。
形式如下:
1 @interface GCTurnBasedMatchHelper : NSObject {
2 BOOL gameCenterAvailable;
3 BOOL userAuthenticated;
4 }
2.另外一种是直接在 @interface : NSObject{}括号之后,用 @property 去定义一个变量。
1 @property (assign, readonly) BOOL gameCenterAvailable;
你会发现,有人会再@interface中定义了变量后,又在 @property中重复定义相同的变量,而且很常见。
结果可能是这样:

1 @interface GCTurnBasedMatchHelper : NSObject {
2 BOOL gameCenterAvailable;
3 BOOL userAuthenticated;
4 }
5
6 @property (assign, readonly) BOOL gameCenterAvailable;

而且你可以单独在@interface中定义变量,而不用@property定义;也可以只用@property去定义,而不在@interface中定义,当然用了@property去定义,一般要在.m文件中用@synthsize去合成相应的setter,getter方法。否则会得到一个警告。当然@synthsize是可选的,但是是Apple推荐的,不用会有什么后果,我没试过,有兴趣的童鞋可以试一下。
那这两种方式有什么区别呢。
1. 只在@interface中定义变量的话,你所定义的变量只能在当前的类中访问,在其他类中是访问不了的;而用@property声明的变量可以在外部访问。
2.用了@property去声明的变量,可以使用“self.变量名”的方式去读写变量。而用@interface的方式就不可以。
3. 这里给出一个链接:http://stackoverflow.com/questions/9702258/difference-between-properties-and-variables-in-ios-header-file 里面讲到: 我英语菜,简单翻一下:
Defining the variables in the brackets simply declares them instance variables.
在括号中定义一个变量只是简单的声明了一个实例变量(实例变量应该指的成员变量)。 博主注:老外对variable 和instance variable是有不同理解的。所以下文中 用了一个模糊的词 ivar。
Declaring (and synthesizing) a property generates getters and setters for the instance variable, according to the criteria within the parenthesis. This is particularly important in Objective-C because it is often by way of getters and setters that memory is managed (e.g., when a value is assigned to an ivar, it is by way of the setter that the object assigned is retained and ultimately released). Beyond a memory management strategy, the practice also promotes encapsulation and reduces the amount of trivial code that would otherwise be required.
声明(和 @synthsize)一个属性会为成员变量生成 getter 和setter方法,根据括号内的标准,在oc中经常用setter和getter 做内存管理,这是很重要的。(例如: 当一个值被赋给这个变量,对象是通过setter函数去分配,修改计数器,并最后释放的)。更高一个层次来说,这种做法也促进了封装,减少了一些不必要的代码。
It is very common to declare an ivar in brackets and then an associated property (as in your example), but that isn't strictly necessary. Defining the property and synthesizing is all that's required, because synthesizing the property implicitly also creates an ivar.
在@interface括号中定义一个变量并用@property 重复定义一次是很普遍的,实际上不是必要的。用@property和@synthszie就够了,因为在用@synthsize合成这个属性的读写方法时就会创建一个变量。
The approach currently suggested by Apple (in templates) is:
目前苹果(在模板中)建议的方法是这样的:
-Define property in header file, e.g.:
先在头文件中定义一个属性
1 @property int gameCenter;
Then synthesize & declare ivar in implementation:
然后在实现文件中 synthsize和declare成这样:
1 @synthesize gameCenter = __ gameCenter;
The last line synthesizes the gameCenter property and asserts that whatever value is assigned to the property will be stored in the __gameCenter ivar. Again, this isn't necessary, but by defining the ivar next to the synthesizer, you are reducing the locations where you have to type the name of the ivar while still explicitly naming it.
最后一行synthsize gameCenter 属性并说明了不管什么值被分配给这个属性,都会存储到_gameCenter这个变量中。 再次说明,这不是必要的,但是,这样写了之后,你能减少输入已经明确命名的变量名。
最后一句的意思you are reducing the locations where you have to type the name of the ivar while still explicitly naming it .不好翻。
据千锋的第2节语法课课程的讲解,这样写之后可以使得 @synthsize 时内部getter方法会展成
1 -(int)gameCenter
2 {
3 return _gameCenter;
4 }
而直接写 @synthsize gameCenter;
setter函数会在内部展开成
1 -(int)gameCenter
2 {
3 return gameCenter;
4 }
注意到:函数名和变量名是一样的。在斯坦福的课程中,白胡子教授也模糊的说道这样的同名有可能带来bug,具体什么bug他没说,我也没见过,所以还是养成这样写的习惯为好。其他语言的getter函数 一般会在变量前加 get;但oc没有,可能是为了与其他语言做区分,算是oc的特色,结果却带来这么个麻烦。
IOS,objective_C中用@interface和 @property 方式声明变量的区别的更多相关文章
- 【转】 IOS,objective_C中用@interface和 @property 方式声明变量的区别
原文: http://blog.csdn.net/ganlijianstyle/article/details/7924446 1.在 @interface :NSObject{} 的括号中,当然N ...
- 网站开发进阶(六)JSP两种声明变量的区别
JSP两种声明变量的区别 在JSP中用两种声明变量的方法,一种是在<%! %>内,一种是在<% %>内.他们之间有什么区别呢?我们直接看一个JSP文件来理解. 代码如下: &l ...
- PHP 闭包获取外部变量和global关键字声明变量的区别
最近在学习workerman的时候比较频繁的接触到回调函数,使用中经常会因为worker的使用方式不同,会用这两种不同的方式去调用外部的worker变量,这里就整理一下PHP闭包获取外部变量和glob ...
- var、let、const声明变量的区别
let和var声明变量的区别:1.let所声明的变量只在let命令所在的代码块内有效.(块级作用域) for(let i=0;i<10;i++){ // ... } console.log(i) ...
- JSP两种声明变量的区别
感谢大佬:https://blog.csdn.net/tiercel2008/article/details/11553899?utm_source=distribute.pc_relevant.no ...
- 关于Let和var声明变量的区别
Let是ES6中添加进来的一个关键字,用于声明变量,其法与var声明变量相同,不同点在于其作用域(块级). 举例可以看出其具体差别 for(var i=0;i<5;i++){ console.l ...
- es6中的let声明变量与es5中的var声明变量的区别,局部变量与全局变量
自己通过看typescript官方文档里的let声明,与阮一峰老师翻译的的es6学习文档,总结以下三点 1.var声明可以多次重复声明同一个变量,let不行 2.let变量只在块级作用域里面有效果,v ...
- ES6的let和var声明变量的区别
关于let的描述 let允许你声明一个作用域被限制在块级中的变量.语句或者表达式.与var关键字不同的是,它声明的变量只能是全局或者整个函数块的. 作用域规则 let声明的变量只在其声明的块或子块中可 ...
- ES6之用let,const和用var来声明变量的区别
var(掌握) 不区分变量和常量 用var声明的变量都是变量,都是可变的,我们可以随便对它进行运算操作.这样当多个人进行同一个项目时,区分变量和常量会越来越难,一不小心就会把设计为常量的数据更改了 ...
随机推荐
- appium+python自动化51-adb文件导入和导出(pull push)
前言 用手机连电脑的时候,有时候需要把手机(模拟器)上的文件导出到电脑上,或者把电脑的图片导入手机里做测试用,我们可以用第三方的软件管理工具直接复制粘贴,也可以直接通过adb命令导入和导出. adb ...
- Windows系统下将目录挂载为一个磁盘并分配盘符
Windows系统下subst可以临时将目录分配一个盘符. 将路径与驱动器号关联. SUBST [drive1: [drive2:]path]SUBST drive1: /D drive1: 指定要分 ...
- Linux编程中的坑——C++中exit和return的区别
今天遇到一个坑,折腾了一天才把这个坑填上,情况是这样的: 写了段代码,在main()函数中创建一个分离线程,结果这个线程什么都没干就直接挂掉了,代码长这样: int main() { 创建一个分离线程 ...
- Oracle 10g数据库备份与恢复操作手册
Oracle 10g数据库备份与恢复操作手册 目录 Oracle 10g数据库备份与恢复操作手册... 前言... 文档目的... 文档范围... 目标读者... 其他说明... 冷备份... 热备份 ...
- TensorFlow进阶(三)---变量的创建、初始化
变量的的创建.初始化.保存和加载 其实变量的作用在语言中相当,都有存储一些临时值的作用或者长久存储.在Tensorflow中当训练模型时,用变量来存储和更新参数.变量包含张量(Tensor)存放于内存 ...
- KMP字符串模式匹配详解(zz)
刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN A_B_ ...
- sparkStreaming读取kafka的两种方式
概述 Spark Streaming 支持多种实时输入源数据的读取,其中包括Kafka.flume.socket流等等.除了Kafka以外的实时输入源,由于我们的业务场景没有涉及,在此将不会讨论.本篇 ...
- (转)nio 字符集
字符集 概述 根据 Sun 的文档,一个 Charset 是“十六位 Unicode 字符序列与字节序列之间的一个命名的映射”.实际上,一个 Charset 允许您以尽可能最具可移植性的方式读写字符序 ...
- centos vim 7.3 升级 + vim 简单配置文件
CentOS5自带VIM为2006年的7.0版本,现在很多插件都是针对7.3开发的,决定编译升级VIM7.3版. 编译安装VIM7.3: cd /usr/local/src/ wget ftp://f ...
- 小程序 的 textarea 组件 层级问题如何解决
像这样的 既然是定位(脱离文档流),为啥不加层级关系,层级关系不明确,很容易出现显示异常,给遮罩加z-index:10,弹出框加z-index:11 即可 解决方案参考: https:// ...