本文转自http://blog.csdn.net/addychen/article/details/39525681

使用Objective-C一段时间了,一直没有弄清楚在Objective-C中属性和实例变量,在这里总结一下,Objective-C中先有的实例变量,需要给外部类使用的用@public声明,内部自己使用的用@private或@protect声明。Objective-C添加了属性后,我觉得Apple的考虑应该是,属性用于对外而实力变量主要用于程序内部使用。这样有利于代码的分离,由于编译器会直接给属性提供对应的实例变量(当然也可以手动指定该属性所对应的实例变量)和getter/setter方法。

类Class中的属性property

在老版本的Objective-C语言中,我们需要同时声明属性和底层实例变量,那时,属性是Objective-C语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如:

  1. @interface MyViewController :UIViewController{
  2. __strong UIButton *_myButton;
  3. }
  4. @property (nonatomic, retain) UIButton *myButton;
  5. @end

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

例如:MyViewController.h文件

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

在MyViewController.m文件中,编译器也会自动的生成一个实例变量_myButton。那么在.m文件中可以直接的使用_myButton实例变量,也可以通过属性self.myButton.都是一样的。

注意这里的self.myButton其实是调用的myButton属性的getter/setter方法。这与C++中点的使用是有区别的,C++中的点可以直接访问成员变量(也就是实例变量)。

例如在Objective-C中有如下代码

.h文件

  1. @interface MyViewController :UIViewController{
  2. __strong NSString *_name;
  3. }
  4. @end

.m文件中,self.name 这样的表达式是错误的。xcode会提示你使用->,改成self->name就可以了。因为oc中点表达式是表示调用方法,而上面的代码中没有name这个方法。

oc语法关于点表达式的说明:”点表达式(.)看起来与C语言中的结构体访问以及java语言汇总的对象访问有点类似,其实这是oc的设计人员有意为之。如果点表达式出现在等号 = 左边,该属性名称的setter方法将被调用。如果点表达式出现在右边,该属性名称的getter方法将被调用。”

所以在oc中点表达式其实就是调用对象的setter和getter方法的一种快捷方式, 例如:dealie.blah = greeble 完全等价于 [dealie.blah setBlah:greeble];

以前的用法,声明属性跟与之对应的实例变量:

  1. @interface MyViewController :UIViewControlle{
  2. __strong UIButton *_myButton;
  3. }
  4. @property (nonatomic, retain) UIButton *myButton;
  5. @end

这种方法基本上使用最多,现在大部分也是在使用,因为很多开源的代码都是这种方式。但是ios5更新之后,苹果是建议以以下的方式来使用:

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

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

@synthesize 还有一个作用,可以指定与属性对应的实例变量,例如@synthesize myButton = xxx;那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。

在实际的项目中,我们一般这么写.m文件

@synthesize myButton;

这样写了之后,那么编译器会自动生成myButton的实例变量,以及相应的getter和setter方法。注意:_myButton这个实例变量是不存在的,因为自动生成的实例变量为myButton而不是_myButton,所以现在@synthesize的作用就相当于指定实例变量;

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

 

(转)Objective-C语言--属性和实例变量的更多相关文章

  1. Objective-C语言--属性和实例变量

    看到一篇讲解特别清晰的blog,与大家共享:http://blog.csdn.net/addychen/article/details/39525681

  2. Objective-C语言介绍 、 Objc与C语言 、 面向对象编程 、 类和对象 、 属性和方法 、 属性和实例变量

    1 第一个OC控制台程序 1.1 问题 Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X,iOS的应用程序.其运行于苹果公司的Mac操作系统下. 本案例要求使用集成 ...

  3. objective-C学习笔记(三)数据成员:属性与实例变量

    类型成员 Type Member 结构体 struct 的成员很简单,只有变量. 类的成员就很多了: 数据成员 data member 描述对象(本讲重点) · 实例变量  instance vari ...

  4. IOS的属性和实例变量

    实际上,@property声明的是属性,并不是实例变量.但是编译器会根据属性,自动生成实例变量,和对应的access方法.所以已经在interface里声明了@property,就不再需要在imple ...

  5. OC 对象调用属性或实例变量或方法的细节。

    1.成员变量可以理解为所有在类的头上声明的,无论是@interface.@implementation下用大括号括起来或者是用@property声明的变量都可以称作这个类的 成员变量,只是在@impl ...

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

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

  7. iOS 成员变量,实例变量,属性变量的区别,联系

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

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

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

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

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

随机推荐

  1. DRF教程3-类视图

    Rewriting our API using class-based views 使用类视图重写root views,只需要一点点重构. from django.http import Http40 ...

  2. SpringMVC-Handler-Return Values返回值

    Handler-Return Values返回值 支持的返回类型列表 Same in Spring WebFlux The table below shows supported controller ...

  3. Python相对导入导致SystemError的解决方案(译)

    原文出处: http://stackoverflow.com/   译文出处:yibohu1899 这个问题是如何解决在相对导入的时候,如果出现’System Error’的时候的解决方案.顺带一提, ...

  4. vuex2 10分钟快速入门

    因为太简单了,我直接就贴代码了~ #建立store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex) export de ...

  5. 第六章 设计程序架构 之 设计实现WebSocket策略

    1. 概述 传统网页的通信方式是请求-响应模式,每次请求-响应都是新的连接.连接的建立和断开也是需要消耗资源的. WebSocket是基于TCP协议,实现单个连接上的双向通信. 本章内容包括: 异步读 ...

  6. vue样式操作与事件绑定

    Vue笔记 1 Vue实例 (VM) var vm = new Vue({    el:'#app', //挂载元素        //数据    data: {        title:'值', ...

  7. android布局带参返回

    package com.lxj.lesson2_3ID19; import com.example.lesson2_3_id19.R; import com.lxj.other.AgeActivity ...

  8. 原创 :xftp SFTP子系统申请已拒绝 请确保SSH链接的SFTP子系统设置有效

    在出现这个错误时候 如果你的远程连接没有问题 那么就执行下面的命令 service sshd restart 搞定!

  9. UVA 247 - Calling Circles (Floyd)

    互相可以打电话是一个传递关系,所以Floyd求传递封包,dfs找一个尽量大的圈. #include<bits/stdc++.h> using namespace std; ; map< ...

  10. 火狐浏览器返回不加载JS

    火狐浏览器 go(-1),返回后不加载JS,谷歌会加载. 总结: Firefox和Safari在back时不会触发load, ready事件! 解决方法: $(window).unload(funct ...