你该知道的OC 方法–GET/SET

你该知道的OC 方法–GET/SET

TOC

  1. 1. 写在前面的话
  2. 2. OC 为什么要有 Set 方法和 Get 方法
  3. 3. Set 方法和 Get 方法
    1. 3.1. set 方法
    2. 3.2. get 方法
    3. 3.3. 成员变量注意的几点规范
    4. 3.4. set 方法和 get 方法实战
    5. 3.5. set 方法和 get 方法的好处
  4. 4. set 方法和 get 方法的调用
  5. 5. 被雪藏的 set 和 get
  6. 6. 内存管理中的 set 方法
    1. 6.1. 基本数据类型的set方法
    2. 6.2. OC 对象类型的 set 方法
  7. 7. 写在最后的话

写在前面的话

大学时期也写博客,比如用WordPress 搭个站啦,用HEXO+GITHUB 搭个博客站啦。。。但是内容比较水也没什么浏览量,全当是做做笔记,咱们公司现以“作业”的形式要求写博客,自己有些抵触情绪,我感觉完全是个人的一种分享没有必要跟学生交作业一样(ps. 仅代表个人意见)。所以,建议把写博客培养成一种乐趣,这样看来前期的强制要求也不失为一种方式方法:)那么,回归技术本文将针对 OC 中 Set 方法 Get 方法写一写自己的几点总结(ps. 本文贴出的代码均需手动管理内存 MRC),希望那些还没搞懂 Set 方法和 Get 方法而且又对OC 有兴趣的比如“鱼哥”,看到这篇文章可以有所斩获。

OC 为什么要有 Set 方法和 Get 方法

其实不只是 OC 这门语言,所有的面向对象的语言都有和这两个方法功能相同的方法,只不过各个语言的语法不同罢了。而且,要回答这个问题我感觉要先从面向对象开发的特性之一的封装开始谈起。那什么是封装?什么是面向对象呢?我靠,这个问题的确是一环扣一环,环环相扣的啊!我就不班门弄斧了。。。不耍流氓,直接贴代码来说一下吧:

#import <Foundation/Foundation.h>

@interface Student : NSObject
{
    // public 意味着所有人都可以用,不安全
    @public
    int _age;
}
@end
@implementation Student
@end

int main()
{
    Student *stu = [[Student alloc] init];

    //暴漏的成员变量,可以随意被修改——这样不好
    stu->_age = 20;        

    [stu release];

    return 0;
}

这是一段非常简陋的代码,勿喷。上述代码安全性不好,可以直接修改我创建出来的学生对象的年龄。你可能会说那直接把 public 换成 private 得了这样外面的人就无法随意改动了,很好!自己都没法访问了!!!那么我们该如何访问成员变量呢?如何对他进行赋值?方法!!! 对象的方法可以直接操作对象的成员变量,而不至于把自己的成员变量暴漏于外部。所以我们想办法创建一个方法,让人们通过方法把值传递给成员变量就安全多了。于是,就有了 set 方法和 get 方法来管理成员的访问。

Set 方法和 Get 方法

set 方法

Set 方法给外界提供一个方法设置成员变量的值,同时可以在方法里面对外面传进来的值进行过滤,以避免传递进来一些乱七八糟的东西。

  1. 它有固定的命名方法和命名规范:
    1. 方法名以 set 开头
    2. set 后面跟上成员变量的名称,成员变量的首字母必须大写
  2. 它返回值一定为void,一定要接受一个参数,而且参数类型跟成员变量类型一致
  3. 形参名称不能与成员变量名相同
  4. set 方法可以在别人传递进来值以后做一些事情,可以监听成员变量值的改变

get 方法

  1. 它有固定的命名方法和命名规范:
    1. 肯定有返回值,返回值类型肯定与成员变量类型一致
    2. 方法名跟成员变量名一样,但是不用写下划线了
    3. 不需要接受任何参数
  2. 它返回对象内部的成员变量

成员变量注意的几点规范

  1. 成员变量都以下划线 _ 开头
  2. 可以跟get方法的名称区分开
  3. 可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量

set 方法和 get 方法实战

那么我们用 set 方法和 get 方法对上述代码进行改进:

#import <Foundation/Foundation.h>

@interface Student : NSObject
{
    int _age;
}
// set 方法
- (void)setAge:(int)age;
// get 方法
- (int)age;
@end
@implementation Student
// set 方法
- (void)setAge:(int)age
{
    // 过滤
    if (age<=0)
    {
        age = 1;
    }
    _age = age;
}
// get 方法
- (int)age
{
    return _age;
}
@end

int main()
{
    Student *stu = [[Student alloc] init];

    [stu setAge:20];

    int age = [stu age];

    NSLog(@"age is %d", age);

    [stu release];

    return 0;
}

set 方法和 get 方法的好处

  • 过滤不合理的值
  • 屏蔽内部的赋值过程
  • 让外界不必关注内部的细节

set 方法和 get 方法的调用

从上面的代码中我们调用 set 方法和 get 方法的方式如下:

[stu setAge:20];
[stu age];

OC 还提供了如下等价的方式:

stu.age = 10;
int age = stu.age;

相信接触过其他编程语言的人会了解点语法,即使没有接触其他编程语言,就在 C 的结构体那一部分,我们访问结构体成员也是有点语法的。不过,这里要注意的是:OC 中点语法这样的方式给成员变量赋值和取值并非是直接访问 stu 对象的成员变量 _age ,这里是方法的调用,而且规范的成员变量名的书写也帮助我们区分这一点:成员变量名都是以下划线开头的。

被雪藏的 set 和 get

在实际的开发中,为了提高开发人员的工作效率,Xcode4.5 及以上版本下的编译器提供了更为搞笑的关键字 @property。只要在类的声明中写好 @property 就可以自动帮我们生成:成员变量的定义和声明、set 和 get 方法的声明和实现。

#import <Foundation/Foundation.h>

@interface Student : NSObject
@property int age;
@end

int main()
{
    Student *stu = [[Student alloc] init];

    [stu setAge:20];

    int age = [stu age];

    NSLog(@"age is %d", age);

    [stu release];

    return 0;
}

有没有感觉一下子代码精简了不少啊!这样我们就可以花更少的时间见在这些简单的代码上。

内存管理中的 set 方法

这里我还要讲一下 set 和 get 方法在内存管理中的活跃表现,至于内存管理这里暂时不深入讲解。来看一下内存管理中 set 方法的活跃身影吧!

基本数据类型的set方法

基本数据类型的 set 方法:

- (void)setAge:(int)age
{
    _age = age;
} 

OC 对象类型的 set 方法

下代码如下:

- (void)setCar:(Car *)car
{
    // 解决重复赋值问题,检测是不是新传进来的对象
    if (car != _car)
    {
        // 旧对象做一次release
        [_car release];

        对新对象做一次retain,同时把它赋值给_car,
        // 这样_car就是最新的车

        _car = [car retain];
    }       
}

写在最后的话

set 方法和 get 方法是 OC 中的两个基本方法,虽然在开发中我们已经基本上不用敲这些东西了,但是总得知道它到底是怎么回事吧!文章中有涉猎一丁点儿内存管理的内容只是为了想把这两个方法说清楚,如果你看不懂那就先了解一下内存管理的内容。希望我的博文可以给看到文章最后的您带来些许的帮助,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注