【Objective-C】06-点语法
前言
在Java中,我们可以通过"对象名.成员变量名"来访问对象的公共成员变量,这个就称为"点语法"。比如:
1.在Student类的第2行定义了一个公共的成员变量age
1 public class Student {
2 public int age;
3 }
2.然后在第5行通过点语法直接给stu的成员变量age赋值

1 public class Test {
2
3 public static void main(String[] args) {
4 Student stu = new Student();
5 stu.age = 10;
6 }
7
8 }

当然,正规的做法是让成员变量私有化,让外界使用公共的get方法和set方法访问成员变量。
3.很多高级语言中都有这种点语法,为了让其他行业的程序员快速上手OC,OC中也引入了点语法,只不过它的含义跟Java不太一样
一、传统的get方法和set方法
在正式学习OC的点语法之前,先来看一下传统的get方法和set方法。定义一个Student类,拥有一个成员变量age和对应的get\set方法。
1.Student.h

1 #import <Foundation/Foundation.h>
2
3 @interface Student : NSObject {
4 int age;
5 }
6
7 - (void)setAge:(int)newAge;
8 - (int)age;
9
10 @end

1> 在第4行定义了一个成员变量age,是@protected权限的,所以外界不能直接访问它
2> 在第7、8行分别声明了age变量的set方法和get方法
2.Student.m

1 #import "Student.h"
2
3 @implementation Student
4
5 - (void)setAge:(int)newAge {
6 age = newAge;
7 }
8
9 - (int)age {
10 return age;
11 }
12
13 @end

1> 在第5行实现了set方法
2> 在第9行实现了get方法
3.main.m
把定义好的Student类放到main函数中使用

1 #import <Foundation/Foundation.h>
2 #import "Student.h"
3
4 int main(int argc, const char * argv[])
5 {
6 @autoreleasepool {
7 Student *stu = [[Student alloc] init];
8
9 // 设置age的值
10 [stu setAge:10];
11
12 // 取出age的值
13 int age = [stu age];
14
15 NSLog(@"age is %i", age);
16
17 [stu release];
18 }
19 return 0;
20 }

1> 在2行包含Student的头文件
2> 在第7行创建Student对象,在第17行释放Student对象
3> 在第10行调用set方法设置age的值
4> 在第13行调用get方法获取age的值
5> 在第15行输出age的值,输出结果如下:
2013-04-08 00:26:19.002 点语法[6164:303] age is 10
这就是OC传统的get方法和set方法的简单使用,对初学者来说,这个语法比较奇怪,因为它的方法调用是用方括号[ ]完成的。因此,OC最终引入了点语法。
二、使用点语法代替传统的get方法和set方法
上面演示了OC传统get\set方法的简单用法,接下来使用点语法来代替。
前面main.m中main函数的代码可以改为:

1 int main(int argc, const char * argv[])
2 {
3 @autoreleasepool {
4 Student *stu = [[Student alloc] init];
5
6 // 设置age的值
7 stu.age = 10; // 等价于[stu setAge:10];
8
9 // 取出age的值
10 int age = stu.age; // 等价于int age = [stu age];
11
12 NSLog(@"age is %i", age);
13
14 [stu release];
15 }
16 return 0;
17 }

1.注意第7行代码,把原来的[stu setAge:10]替换成了stu.age = 10。听清楚了,这两种写法是完全等价的。即这里的stu.age并不是代表直接访问stu对象的成员变量age,而是编译器遇到stu.age = 10的时候会自动将代码展开成[stu setAge:10]

再说,如果是直接访问成员变量的话,OC中应该是这样的语法:stu->age,而不是stu.age。
2.注意第10行代码,把原来的int age = [stu age]替换成了int age = stu.age。这两种写法又是完全等价的,stu.age并不是直接访问stu对象的成员变量age,而是编译器遇到int age = stu.age的时候会自动将代码展开成int age = [stu age]

3.因此,OC中点语法的含义跟Java是完全不一样的,OC点语法的本质是方法调用,不是直接访问成员变量。至于这个点语法代表的是get方法还是set方法,那就取决于你是取值还是设值,取值就是get方法(如第10行代码),设值就是set方法(如第7行代码)。
4.如果你想验证点语法是不是方法调用的话,有很多方法。
比如你可以在Student.m的set方法和get方法内部用NSLog加一些打印信息,如果程序运行后有输出打印信息,说明的确是调用了get方法或者set方法

1 #import "Student.h"
2
3 @implementation Student
4
5 - (void)setAge:(int)newAge {
6 NSLog(@"调用了setAge方法");
7 age = newAge;
8 }
9
10 - (int)age {
11 NSLog(@"调用了age方法");
12 return age;
13 }
14
15 @end

三、点语法和self的陷阱
1.在Java中,this关键字代表着方法调用者,也就是说,谁调用了这个方法,this就代表谁。所以一般会这样写set方法:
1 public void setAge(int newAge) {
2 this.age = newAge;
3 }
第2行表示将newAge参数的值,赋值给方法调用者的成员变量age
2.OC中有个self关键字,作用跟this关键字类似。我这么说完,可能有人就会想这样写OC的set方法了:
1 - (void)setAge:(int)newAge {
2 self.age = newAge;
3 }
第2行中的self代表着当前调用setAge:方法的对象。但是第2行代码是绝对错误的,会造成死循环。因为我在前面已经说过了,OC点语法的本质是方法调用,所以上面的代码相当于:
1 - (void)setAge:(int)newAge {
2 [self setAge:newAge];
3 }
很明显,会造成循环调用setAge:方法,程序就这样崩溃了
四、一点小建议
如果是第一次接触OC的点语法,你可能会真的以为stu.age的意思是直接访问stu对象的成员变量age。其实,有一部分原因是因为我这里定义的Student类的成员变量名就叫做age。为了更好地区分点语法和成员变量访问,一般我们定义的成员变量会以下划线 _ 开头。比如叫做 _age 。
1.Student.h,注意第4行

1 #import <Foundation/Foundation.h>
2
3 @interface Student : NSObject {
4 int _age;
5 }
6
7 - (void)setAge:(int)newAge;
8 - (int)age;
9
10 @end

2.Student.m,注意第6行和第10行

1 #import "Student.h"
2
3 @implementation Student
4
5 - (void)setAge:(int)newAge {
6 _age = newAge;
7 }
8
9 - (int)age {
10 return _age;
11 }
12
13 @end
【Objective-C】06-点语法的更多相关文章
- Objective-C( 语法二)
分类(Category):可以给某一个类扩充一些方法(不修改原来类的代码) 作用:在不改变原来类内容基础上,可以为类增加一些方法 使用注意: 1. 只能增加方法,不能增加成员变量 2. 分类方法 ...
- 06.python语法入门--与用户交互、运算符
与用户交互 输入 input # python2与python3的区别 '''python3''' # 将获取到的用户输入赋值给变量名res res = input(' ...
- Swift翻译之-Swift语法入门 Swift语法介绍
目录[-] Hello world - Swift 简单赋值 控制流 函数与闭包 对象和类 枚举与结构 协议和扩展 泛型 2014.6.3日,苹果公布最新编程语言Swift,Swift是一种新的编程语 ...
- Project Management Process
Project Management ProcessDescription .............................................................. ...
- HTML+CSS笔记 CSS进阶
文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...
- sublime从官网纯净版到插件完整版
01.纯净版下载地址:www.sublimetext.com/ 02.下载Package Control插件管理工具,网址:https://packagecontrol.io/ 安装介绍:https: ...
- JavaScript条件语句-5--if语句的嵌套
JavaScript条件语句 学习目标 1.掌握length属性的应用 2.掌握if语句的嵌套 length 语法:string.length 功能:获取string字符串的长度 返回值:number ...
- Automake
Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...
- Objective - C中属性和点语法的使用
一.属性 属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性 ...
- iOS开发核心语言Objective C —— 面向对象思维、setter和getter方法及点语法
本分享是面向有意向从事iOS开发的伙伴们.或者已经从事了iOS的开发人员.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基础,建议您先翻阅我之前分享的iOS ...
随机推荐
- nginxtomca负载均衡
Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性: 作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 ...
- iOS:文本视图控件UITextView的详细使用
文本视图控件:UITextView 介绍:它是一个文本域的编辑视图,可以在该区域上进行编辑(包括删除.剪贴.复制.修改等),它与文本框UITextField的不同之处是:当它里面的每一行内容超出时,可 ...
- all-oone-data-structure(好)
哈哈,我用了HashMap, 双向链表,还有了HashSet来保存key的集合. 现在这道题目还只有 9.3%的AC率,难度为HardTotal Accepted: 9 Total Submissio ...
- python 机器学习中的数据处理学习记录
在机器学习中,选择合适的算法固然重要,但是数据的处理也同样重要.通过对数据的处理,能提高计算效率,提高预测识别精确度等等 以下记录下一些数据处理的方法 一.处理缺失值 对于数据集中有缺失值的,粗暴的方 ...
- Hibernate:SQL查询 addScalar()或addEntity()
Hibernate除了支持HQL查询外,还支持原生SQL查询. 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口.该 ...
- Spark Streaming数据清理内幕彻底解密
本讲从二个方面阐述: 数据清理原因和现象 数据清理代码解析 Spark Core从技术研究的角度讲 对Spark Streaming研究的彻底,没有你搞不定的Spark应用程序. Spark Stre ...
- 提取nds游戏的音乐
nds游戏绝对是游戏界的瑰宝,尤其是有些游戏的音乐还很好听,所以想把它们提取出来.网上搜了下教程,这里整理一下,全程在archlinux下操作. 首先用到的工具是(vgmtrans)[https:// ...
- javascript——正則表達式
正則表達式(RegExp对象):主要用于表单验证 1.创建正則表達式: (1).var ret = /pattern/; pattern是内容.能够是正則表達式的内容,能够是字符或是其它的内容 (2) ...
- 云计算之路-Azure vs 阿里云:从负载均衡中摘/挂虚拟机
@小尾鱼 在 试用Azure:上不了高速的跑车,无法跨Cloud Service的DNS服务器一文的评论中提了一个很好的问题: 问个问题,使用了负载均衡以后,程序发布的时候博客园是怎么避免用户访问到正 ...
- Android系统常用的权限
开机自动允许 android.permission.RECEIVE_BOOT_COMPLETED,允许程序开机自动运行. 电量统计 android.permission.BATTERY_STATS ...