• 【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和对应的getset方法。

    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传统getset方法的简单用法,接下来使用点语法来代替。

    前面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
  • 相关阅读:
    js点击弹出div层
    图片按比例缩小
    js标题文字向上滚动
    JS刷新当前页面
    图片缩放显示,不变形
    产品叠加搜索
    Oracle中DML基础知识
    Oracle中DDL的基础知识
    Sql多对多关系中外键的应用
    oracle 中sql语句的几个基本函数..
  • 原文地址:https://www.cnblogs.com/LiLihongqiang/p/5622423.html
Copyright © 2020-2023  润新知