在Java中,咱们能够经过"对象名.成员变量名"来访问对象的公共成员变量,这个就称为"点语法"。好比:java
1.在Student类的第2行定义了一个公共的成员变量age程序员
1 public class Student { 2 public int age; 3 }
2.而后在第5行经过点语法直接给stu的成员变量age赋值函数
public class Test { public static void main(String[] args) { Student stu = new Student(); stu.age = 10; } }
固然,正规的作法是让成员变量私有化,让外界使用公共的get方法和set方法访问成员变量。学习
3.不少高级语言中都有这种点语法,为了让其余行业的程序员快速上手OC,OC中也引入了点语法,只不过它的含义跟Java不太同样this
在正式学习OC的点语法以前,先来看一下传统的get方法和set方法。定义一个Student类,拥有一个成员变量age和对应的get\set方法。spa
#import <Foundation/Foundation.h> @interface Student : NSObject { int age; } - (void)setAge:(int)newAge; - (int)age; @end
1> 在第4行定义了一个成员变量age,是@protected权限的,因此外界不能直接访问它code
2> 在第七、8行分别声明了age变量的set方法和get方法orm
#import "Student.h" @implementation Student - (void)setAge:(int)newAge { age = newAge; } - (int)age { return age; } @end
1> 在第5行实现了set方法对象
2> 在第9行实现了get方法ci
把定义好的Student类放到main函数中使用
#import <Foundation/Foundation.h> #import "Student.h" int main(int argc, const char * argv[]) { @autoreleasepool { Student *stu = [[Student alloc] init]; // 设置age的值 [stu setAge:10]; // 取出age的值 int age = [stu age]; // 打印 NSLog(@"age is %i", age); [stu release]; } return 0; }
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最终引入了点语法。
上面演示了OC传统get\set方法的简单用法,接下来使用点语法来代替。
前面main.m中main函数的代码能够改成:
int main(int argc, const char * argv[]) { @autoreleasepool { Student *stu = [[Student alloc] init]; // 设置age的值 stu.age = 10; // 等价于[stu setAge:10]; // 取出age的值 int age = stu.age; // 等价于int age = [stu age]; NSLog(@"age is %i", age); [stu release]; } return 0; }
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方法
#import "Student.h" @implementation Student - (void)setAge:(int)newAge { NSLog(@"调用了setAge方法"); age = newAge; } - (int)age { NSLog(@"调用了age方法"); return age; } @end
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行
#import <Foundation/Foundation.h> @interface Student : NSObject { int _age; } - (void)setAge:(int)newAge; - (int)age; @end
2.Student.m,注意第6行和第10行
#import "Student.h" @implementation Student - (void)setAge:(int)newAge { _age = newAge; } - (int)age { return _age; } @end
注:本文转自M了个J博客。