在ios第一版中:

  我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如:

  注意:(这个是以前的用法)

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

  在现在iOS版本中:

  苹果将默认编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了。如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量。因此,在这个版本中,我们不再为输出口声明实例变量。

  ios5更新之后,苹果是建议以以下的方式来使用:

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

  因为编译器会自动为你生成以下划线开头的实例变量_myButton,不需要自己手动再去写实例变量。而且也不需要在.m文件中写@synthesize myButton,也会自动为你生成setter,getter方法。

  @synthesize的作用:(1)让编译器为你自动生成setter与getter方法。(2)可以指定与属性对应的实例变量,例如@synthesize myButton = xxx;那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。

  现在:如果.m文件中写了@synthesize myButton,那么生成的实例变量就是myButton;如果没写@synthesize myButton,那么生成的实例变量就是_myButton。所以跟以前的用法还是有点细微的区别。

二、实例变量与属性变量使用方法

  在MyViewController.m文件中,编译器也会自动的生成一个实例变量_myButton。那么在.m文件中可以直接的使用_myButton实例变量,也可以通过属性self.myButton.都是一样的。用self.yourButton来访问yourButton变量是不对的,Xcode会提示你使用->,改成self->yourButton就可以了。因为OC中点的表达式是表示调用yourButton方法,而上面代码没有yourButton方法,也可以直接使用yourButton。

三、类别中的属性property

  类与类别中添加的属性要区分开来,因为类别中只能添加方法,不能添加实例变量。经常会在ios的代码中看到在类别中添加属性,这种情况下,是不会自动生成实例变量的。比如在:UINavigationController.h文件中会对UIViewController类进行扩展

@interface UIViewController (UINavigationControllerItem)
@property(nonatomic,readonly,retain) UINavigationItem *navigationItem;
@property(nonatomic) BOOL hidesBottomBarWhenPushed;
@property(nonatomic,readonly,retain) UINavigationController *navigationController;
@end

  这里添加的属性,不会自动生成实例变量,这里添加的属性其实是添加的getter与setter方法。

  注意一点,匿名类别(匿名扩展)是可以添加实例变量的,非匿名类别是不能添加实例变量的,只能添加方法,或者属性(其实也是方法)。

四、成员变量、实例变量、属性变量的联系

@interface MyViewController :UIViewControlle
{
UIButton *yourButton;
int count;
id data;
}
@property (nonatomic, strong) UIButton *myButton;
@end

  在{   } 中所声明的变量都为成员变量。 所以yourButton、count、data都是成员变量。既然如此,实例变量又是什么意思呢?

  实例变量本质上就是成员变量,只是实例是针对类而言,实例是指类的声明。{   }中的yourButton就是实例变量。id 是OC特有的类,本质上讲id等同于(void *)。所以id data属于实例变量。

  成员变量用于类内部,无需与外界接触的变量。因为成员变量不会生成set、get方法,所以外界无法与成员变量接触。根据成员变量的私有性,为了方便访问,所以就有了属性变量。属性变量的好处就是允许让其他对象访问到该变量(因为属性创建过程中自动产生了set 和get方法)。当然,你可以设置只读或者可写等,设置方法也可自定义。所以,属性变量是用于与其他对象交互的变量。

  综上所述可知:成员变量是定义在{}号中的变量,如果变量的数据类型是一个类则称这个变量为实例变量。因为实例变量是成员变量的一种特殊情况,所以实例变量也是类内部使用的,无需与外部接触的变量,这个也就是所谓的类私有变量。而属性变量是用于与其他对象交互的变量。

  但是,现在大家似乎都不怎么喜欢用成员变量来定义类的变量,都喜欢用属性变量来定义类的变量。把需要与外部接触的变量定义在.h文件中,只在本类中使用的变量定义在.m文件中。

首先来区别一下实例变量、成员变量的区别:
 

可以看到在接口 @interface 括号里面的统称为”成员变量”,实例变量是成员变量中的一种!
实例变量的英文翻译是 Instance Variable (object-specific
storage) 
实例的英文翻译为Instance(manifestation 
of a 
class) 
说的是“类的表现”,说明实例变量应该是由类定义的变量!
除去基本数据类型int float ....等,其他类型的变量都叫做实例变量。

**实例变量+基本数据类型变量=成员变量**
 
接下来说说属性:
 
在@property(描述1 , 描述2 , 描述3)(class *) varName 里面,有3个描述词需要填写(也可以不填写取默认值)
1. nonatomic<-->atomic
2. readwrite<-->readonly
3. retain/copy/assign
 
首先来介绍一下:
retain:他指的是将某个内存区域的指针赋值给变量,同时把该内存区域的引用计数器加1.每执行一次,该内存区域的引用计数器就要加1,当该区域的引用计数器变为0的时候内存区域被释放!
 
copy:它指的是将目标内存区域的值复制一份,然后开辟新的内存区域(新的指针)粘贴这个值。同时变量被赋值为新内存区域的指针!
 
assign:它指的是,仅只把目标内存区域的指针赋值给变量,该内存区域的引用计数器不发生变化!
 
1、2两点不做解释,3中的retain、copy、assign都是指的,在自动生成setter函数的时候,编译器需要识别个描述词来生成对应的setter函数!需要注意的是,如果没有加上该类的描述词,系统默认该变量的setter方法采取assign的方式。
在头文件中.h一般在{}里面会有定义的实例变量  
 
示例:
.h
@property (automic,retain) NSString * abc;
.m
@sythesize abc;
 

//在写了@sythesize abc;的情况下,系统不会自动生成实例变量“_abc”,直接通过变量名abc ,也就是直接使用变量名在赋值运算的时候(=号左边),只是将内存区域的指针赋值给变量,相当于assgin.   如果是通过“点语句”self.abc= 来赋值,就要看在@property中定义的是copy、retain、assign哪一种了,如果没有加上上述描述词,就默认为assign。

//如果没有写@sythesize abc;  系统会默认自动在.h文件{}中添加一个 不可见的 加“_”的成员变量(即使是变量名中本身就带有“_”)

//括号里面定义的都是成员变量(基本数据类型+类生成变量),里面的变量可以在.m文件中通过“变量名称”、self->“变量名称”直接访问到括号里面的变量,但是,这样的赋值访问只能是assign,原对象的引用计数器不会发生变化。

//1.@sythesize 变量名;2.@sythesize 变量名=_变量名;3.不写@sythesize (一下提到的变量名都是指的在头文件中@property 中定义的变量)

1.成员变量,实例变量通过“变量名”或者self->“变量名”直接访问到,赋值(assign)。self.变量名 实现setter,getter方法。

2.成员变量,实例变量通过“_变量名”或者self->“_变量名”直接访问到,赋值(assign)。self.变量名 实现setter,getter方法。

3.成员变量。实例变量(系统自动在原来变量名前加上“_”来生成的实例,成员变量),直接通过self->_变量名,或者变量名直接访问到(assign)。self.变量名 实现setter,getter方法。

如果在头文件中没有通过@property定义的变量,但是在{}中有定义成员变量,在实现文件中也也没有@sythesize ,那么可以直接通过self->“{}中的变量名”,或者直接使用“{}中的变量名”来访问赋值,这样的变量没有定义setter,getter函数,只能是assign的方式赋值。

//再来分析一下@sythesize中的写法,@sythesize abc 直接在.m文件中使用self.abc可以调用成员变量的setter、getter函数,直接调用成员变量名称abc就为访问该变量的指针,对成员变量直接赋值等同于ASSIGN效果。

iOS 成员变量,实例变量,属性变量的区别,联系的更多相关文章

  1. ios -- 成员变量、实例变量与属性的区别

      最近打开手机就会被胡歌主演的<猎场>刷屏,这剧我也一直在追,剧中的郑秋冬,因为传销入狱五年,却在狱中拜得名师孙漂亮(孙红雷),苦学HR,并学习了心理学,成功收获两样法宝.出狱后因为怕受 ...

  2. iOS成员变量、实例变量、属性变量三者的联系与区别

    一.类Class中的属性property 在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是 ...

  3. iOS中的成员变量,实例变量,属性变量

    在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是以前的用法) @interface MyV ...

  4. OC基础成员变量、属性变量、实例方法与类方法

    首先,为什么我们要定义一个新类呢?按照我的理解,就是为了抽象出来一个新的东西(也就是类),用来存储更多的数据变量和方法,一切类都直接或间接继承与NSObject. 在类的头文件里我们可以定义成员变量. ...

  5. iOS 成员变量和属性的区别

    一. 成员变量 1.成员变量的作用范围: @public:在任何地方都能直接访问对象的成员变量 @private:只能在当前类的对象方法中直接访问,如果子类要访问需要调用父类的get/set方法 @p ...

  6. IOS 成员变量,全局变量,局部变量定义,static与extern的区别

    IOS 成员变量,全局变量,局部变量定义,static与extern的区别 1,先说定义 1)成员变量定义:生存与该类的生命周期,变量存活周期跟你定义的该类实体对象一样:作用域是整个实体对象:可以在h ...

  7. java局部/成员/静态/实例变量

    局部变量和成员变量主要是他们作用域的区别成员变量个是类内部:局部变量是定义其的方法体内部(或者方法体内部的某一程序块内——大括号,主要看定义的位置).另外,成员变量可以不显式初始化,它们可以由系统设定 ...

  8. python的类变量与实例变量以及__dict__属性

    关于Python的实例变量与类变量,先来看一段可能颠覆世界观的例子 #!/usr/bin/env python # -*- coding: utf_8 -*- # Date: 2016年10月10日 ...

  9. 定义一个Person类,其中包括:1.定义属性:姓名、年龄、民族作为成员变量。定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化。3.定义多个方法:分别显示相应的属性值,例如getName(){System.out.print("名称="+name+";"); }4.定义一个方法“成长”:实现年龄的增加,每执行一次年龄增加1

    题目显示不全,完整题目描述: (1)定义一个Person类,其中包括:1.定义属性:姓名:年龄:民族作为成员变量.定义静态成员变量:人数2.定义构造方法:对成员变量进行初始化.3.定义多个方法:分别显 ...

随机推荐

  1. JQuery好用的日期选择控件 DatePicker

    近期发现一个很好的基于JQ的前端UI日期选择控件Jquery.DatePicker.js 下载地址:jquery.DatePIcker.js 演示地址:DatePicker - 基于jQuery 1. ...

  2. unix文件权限

    一.UNIX下关于文件权限的表示方法和解析 SUID 是 Set User ID, SGID 是 Set Group ID的意思. UNIX下可以用ls -l 命令来看到文件的权限.用ls命令所得到的 ...

  3. Spark Streaming 架构

    图 1   Spark Streaming 架构图 组件介绍:‰ Network Input Tracker : 通 过 接 收 器 接 收 流 数 据, 并 将 流 数 据 映 射 为 输 入DSt ...

  4. Java常用命令行工具

    命令基于Sun JDK,用于监控和诊断HotSpot的java 虚拟机. 对应的可执行文件位于$JAVA_HOME/bin/下 jps-虚拟机进程状况工具 选项 作用 -q 只输出LVMID,同进程p ...

  5. Hibernate入门(1)-第一个Hibernate程序

    Hibernate入门(1)-第一个Hibernate程序 Hibernate是最著名的ORM工具之一,本系列文章主要学习Hibernate的用法,不涉及Hibernate的原理.本文介绍第一个Hib ...

  6. Spring入门(9)-AOP初探

    Spring入门(9)-AOP初探 0. 目录 什么是面向切面编程 AOP常见术语 AOP实例 参考资料 1. 什么是面向切面编程 Aspect Oriented Programming(AOP),即 ...

  7. HDU 1312 http://acm.hdu.edu.cn/showproblem.php?pid=1312

    #include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #de ...

  8. jquery easyui鼠标右击显示自定义的菜单

    1.datagrid表格中,对某一行鼠标右击,显示出如下的自定义的菜单: 在html页面中写: <div id="menu" class="easyui-menu& ...

  9. CUDA常见问题之无法在c文件中调用cu文件中定义的函数

    当在C源文件中调用cu文件中定义的函数时,会出现undefined reference的问题,而在C++源文件中调用cu文件中定义的函数时则不会出现这个问题. 出现上述问题的原因是,nvcc编译器采用 ...

  10. hdu2248

    纷菲幻剑录 之 十年一剑 Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...