Objective-c下变量和属性的区别

随着苹果将默认的编译器从GCC换成了LLVM,编译器自动为一个属性生成对应的变量和setter/getter方法,我们已经越来越习惯在自己创建的类中直接通过声明一个属性来创建一个类变量了。比如:

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, strong) NSString* name;
@property (nonatomic) int age;

-(void)func;
-(instancetype)init;
-(void)setName:(NSString *)name;
-(NSString*) name;
@end

但是却忽视了属性和变量本质上的区别,导致在使用中遇到很多奇怪的问题无法理解,尤其是在非ARC下这种情况就更是如此。

在最早的iOS编程中,我们必须为每一个属性声明一个对应的变量,两者相互配合使用,比如:

@interface MyViewController :UIViewController
{
    UIButton *myButton;
}
@property (nonatomic, retain) UIButton *myButton;
@end

但是现在我们并不需要这么写,只需要声明一个属性比如name,那么编译器就会自动为其声明一个对应的变量_name。在我看来,所谓属性,其实本质还是对变量的管理,属性可以看做是对变量的封装,通过封装变量一来可以方便开发,省略了大量的setter/getter方法的编写。同时也避免了直接操作变量的不安全性。在此基础之上,属性还有多个附加特性:nonatomic、strong、weak、copy、atomic等等,使得原本复杂的线程安全、retain/release机制等都可以通过简单的属性申明而避免,大大方便了程序开发。由此看来,属性确实是Objective-c相对于其他语言一个重要的优势。

变量

Objective-c下传统的变量并没有太多的区别:公有、私有以及保护变量:

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
@private
    int privateVar;
@public
    int publicVar;
@protected
    int protectedVar;
}

@end

其含义和C++、Java等语言也一样:公有变量可以在类外部访问;私有变量仅能在类内部访问且不能被子类访问;保护变量仅能在类内部和子类访问。在Objective-c中访问类变量的语法是:self->privateVar。注意必须要使用类似C++下指针的访问方式,如果使用.语法是无法访问变量的。使用诸如self->privateVar的语法访问变量就是直接操作变量,这时变量操作的安全性都是由编码者自己负责。尤其是在操作涉及到内存操作的时候需要格外小心,最典型的使用场景就是在对诸如NSString*等类型的变量进行赋值操作时候的retain和release操作:

-(void)setPrivateVar:(NSString*)var
{
    if(self->privateVar == var)
        return;
    [var retain];
    [self->privateVar release];
    self->privateVar = var;
    return;
}

点语法

还有一点值得注意的就是,在使用属性之后,编译器不仅为对应的变量自动生成setter/getter方法,同时还简化了调用两种方法的方式:点语法。在Objective-c中p.name = @"liyazhou",这样一个语句并不是像在c++或者java下直接操作一个实例的类成员变量,而实际上是调用了对应的setter方法,所以p.name = @"liyazhou"调用的语句是[p setName:@"liyazhou"]。而return p.name实际上等价于return
[p getName];

以上就是Objective-c下面属性和变量最基本的区别和联系。总的来说属性的出现大大简化了Objective-c的编程,但同时也使初学者混淆了相关概念,稀里糊涂之下随便使用,知其然不知其所以然,遇到问题不知所措。所以想要放心大胆地使用一些便利而强大的编程特性就必须对其背后的原理烂熟于胸才行。

时间: 2024-10-27 07:57:26

Objective-c下变量和属性的区别的相关文章

Equals和==的区别 公共变量和属性的区别小结_实用技巧

Equals 和==的区别 C#中有两种不同的相等:引用相等和值相等 == 是比较两个变量的值是否相同或两个引用是不是指向同一个内存地址. Equals()方法是比较两个对象指向内存空间里的内容是不是相同.也就是比较两个"引用类型" 是否是对同一对象的引用,即两个对象的内容是否相同. 公共变量和属性的区别 变量对于类本身而言,称为域. 属性是类的外部显示出来的特性,只是公开属性,如何进行赋值(set)和如何进行取值(get)都进行了封装,对于类外部是不可见的.对于外部使用者来说只能够使

struts标签-struts下的jsp文件中html:select 下的各个属性有哪些

问题描述 struts下的jsp文件中html:select 下的各个属性有哪些 struts下的jsp文件中html:select 下的属性property,styleIdonchange分别是什么意思啊这行struts的jsp代码是什么意思,哪位朋友能说一下,十分感谢 解决方案 1.property 是 ActionForm里定义的变量,就相当于html标签里面的name属性如 被解析后和html语句是一样的只是用了struts的property属性就得有想对应formBean,否则报错.2

java中成员变量与局部变量的区别

成员变量与局部变量的区别 1.在类中的位置不同 成员变量:在类中方法外面 局部变量:在方法或者代码块中,或者方法的声明上(即在参数列表中) 2.在内存中的位置不同,可以看看 Java程序内存的简单分析 见 接下来我们再通过一段程序来直观感受下程序运行时JVM的内存情况, package demo; public class Student {     private String name;     private int age;     public void study() {      

全编辑WebGrid控件LrcGrid(5)—— 构造函数、变量和属性

web|变量|函数|控件 全编辑WebGrid控件LrcGrid(5)-- 构造函数.变量和属性 LrcGrid从System.Web.UI.WebControls.Table继承,实现INamingContainer接口 元数据属性和构造函数:元数据声明了控件的标签和默认属性,构造函数为控件一些属性指定了默认值. [ ToolboxData("<{0}:LrcGrid runat=server></{0}:LrcGrid>"), DefaultProperty

WinForm控件开发总结(九) 为属性提下拉式属性编辑器

在上一篇文章,我介绍了如何编写模态对话框属性编辑器,这篇文章我将介绍如何编写下拉式属性编 辑器.下拉式(DropDown)属性编辑器和模态对话框属性编辑器的不同之处就是,当你点击属性值修改的 时候,模态对话框编辑器是弹出一个模态对话框,而下拉式属性编辑器却是在紧贴着属性值的地方显示一 个下拉的控件.不知道大家注意到了没有,这里我说的是显示一个下拉的控件,而这个控件也是需要你去 开发的,接下来我还是以Scope属性为例,介绍一下具体的实现. 首先我们要创建一个用于编辑属性的控件,在本系列文章的开始

iOS开发:学习笔记—变量、属性、方法、实现

  1.代码说明: Person.h 开发:学习笔记-变量.属性.方法.实现-"> Person.h #import @interface Person : NSObject { int age,sex;//变量的定义 int height,width; } @property int age,sex;//属性的定义 @property char height; //-(void) setAge; -(int) setAge1 :(int)a; -(int) setWH :(int)w :

XP系统下解决显示属性丢失“桌面”选项

  windows xp系统下的显示属性丢失"桌面"选项 卡应该怎么办?系统大全告诉你应该如何解决. 方法一 单击"开始"--"运行"命令,在"运行"对话框的"打开"栏中键入"gpedit.msc"命令,然后单击"确定". 打开组策略编辑器,在左侧窗格中展开"用户配置"--"管理模板"--"控制面板"--&q

readonly和disabled属性的区别_基础知识

标签的readonly和disabled属性的区别: 在表单元素中,readonly和disable有类似之处,因为它们都可以将一些表单元素设置为"不可用"状态,当然它们之间的区别是巨大的,下面就介绍一下这个两个属性有哪些区别,希望能够给需要的朋友带来一定的帮助. 两个属性不同点列举: 1.readonly属性只对表单元素的文本框.密码框和多行文本框有效,而disabled属性对所有的表单元素都会有效. 2.设置两个属性的外观不一样,这个自己可以观察一下. 3.设置readonly的表

javascrpit-ie 8 下设置bodyzoom属性125%之后页面向右靠 ,有办法解决么 ?chrome下正常

问题描述 ie 8 下设置bodyzoom属性125%之后页面向右靠 ,有办法解决么 ?chrome下正常 各位亲 有办法解决么 ?就是最后起到放大 页面的效果,结果 ie和chrome的效果不一致 解决方案 设 margin-left:-25px; 在css属性最后添加表示只有ie能识别.居然在百度知道有人回答了,特意把回答站过来原回答地址:http://zhidao.baidu.com/question/369696797863553324.html