oc学习笔记-成员变量

本文介绍了Objective-C中的成员变量,包括定义、访问方式以及默认初始化。详细阐述了直接访问、通过实例方法访问和点语法的使用。同时,文章还探讨了单例模式的概念,解释了如何实现单例类,确保一个类在整个程序中只存在一个实例。通过示例代码展示了单例模式的创建过程及其工作原理。
摘要由CSDN通过智能技术生成

成员变量

什么是成员变量

成员变量指的是在类接口部分或类实现部分定义的变量,oc中成员变量都是实例变量。
成员变量类似于c语言中的结构体,下面实现了中类接口部分定义成员变量:

#import <Foundation/Foundation.h>

@interface FKPerson : NSObject {
    //下面定义了两个成员变量
    @private
    NSString* _name;
    int _age;
}
// 下面定义了一个 setName: 方法
- (void) setName: (NSString*) name;
// 获取name
- (NSString*) name;
// 提供方法设置age成员变量
- (void) setAge: (int) age;
// 获取age
- (int) age;
@end

注意的点:当我们定义成员变量时应该以下划线开头。

如何访问实例变量

1.直接访问

只要实例存在,程序就可以访问该成员变量,
oc提供了直接访问成员变量的语法:
实例->实例变量
例如访问上面定义的成员变量_name
代码如下:

#import "FKPerson.h"

int main(void) {
    @autoreleasepool {
        FKPerson *p1 = [[FKPerson alloc] init];
        p1->_name = @"李刚";
        NSLog(@"name: %@", p1->_name);
    }
}

但此时程序会报错,虽然我们使用了正确的语法p1->_name,但在我们的类接口部分我们使用了@private指令,所以无法直接访问,我们应该将指令修改成@public即可使用直接访问。

2.使用自己定义的实例方法

当我们给成员变量使用@protected或者@private时无法在主函数中直接访问成员变量,这时我们可以利用自己定义的方法,接下来,自己定义实例方法非常简单,就是在类接口部分声明方法,在实现部分完成定义即可。实现代码如下所示:

#import "FKPerson.h"

@implementation FKPerson

// 提供方法来设置name成员变量
- (void) setName:(NSString *) name {
    //检查合理性,要求用户名必须在2-6位之间
    if ([name length] > 6 || [name length] < 2) {
        NSLog(@"您设置的人名不符合要求");
        return;
    } else {
        _name = name;
    }
}
// huoqu name
- (NSString*)name {
    return _name;
}
// 提供方法来设置age成员变量
- (void) setAge: (int) age {
    if (_age != age) {
        //检查合理性,要求age必须在0-100位之间
        if (age > 100 || age < 0) {
            NSLog(@"您设置的年龄不合法");
            return;
        } else {
            _age = age;
        }
    }
}
- (int) age {
    return _age;
}
@end

代码中的age和name就是我们定义的方法。
就可以在主函数中调用了:

int main(void) {
    @autoreleasepool {
        FKPerson *p1 = [[FKPerson alloc] init];
        [p1 setAge:18];
        [p1 setName: @"李刚"];
        NSLog(@"name: %@, age: %d", [p1 name], [p1 age]);
    }
}

3.点方法

当一个成员变量有getter 和 setter方法时,即可运用点方法调用,点方法的实质就是调用setter和getter方法。
例如修改上面的成员变量代码如下:

int main(void) {
    @autoreleasepool {
        FKPerson *p1 = [[FKPerson alloc] init];
        p1.age = 19;
        p1.name = @"ligang";
        NSLog(@"name: %@, age: %d", [p1 name], [p1 age]);
    }
}

点方法和我们创建的方法一样,是可以在不同指令下访问成员变量的。

成员变量的一些运行机制

成员变量无需显式初始化,只要为一个类定义了实例变量,系统会默认初始化实例变量,基本类型的成员变量被默认为0,指针变量被默认为nil(空指针类型类似于c语言NULL)。
例如上面代码中我们定义的对象p1,如果不对其成员变量_age赋值,那么我们在输入其时值为0.

单例(Singleton)模式简介

单例模式主要用于反复创建,销毁同一个类的程序。
创建一个始终只能创建一个实例的单例类,可以提高程序的性能。

如何实现单例类

单例类可通过static全局变量实现,程序考虑定义一个static全部变量,该变量用于保护已经创建的SIngleton对象——每次程序需要获取该实例时,首先会判断static全局变量是否为nil,如果该全局变量为nil,则会初始化一个实例并赋值给static全局变量。
下面是实现一个单例类的代码。
首先是类接口部分:

#import <Foundation/Foundation.h>


@interface FKSingleton : NSObject
// 声明一个类方法允许程序通过该方法获得该类的唯一实例
+ (id) instance;
@end

类实现部分:在类实现部分我们利用了一个static全局变量,在最开始我们没有创建实例时,它的值为nil。
这里介绍一下static的简单用法:
1.可以修饰局部变量,将局部变量存储到静态存储区。
2.可以修饰全局变量,限定全局变量只能在当前源文件中访问。
3.可以修饰函数,限定该函数只能在当前源文件调用。
这里static的作用是:类方法不可以访问实例变量,通过static修饰的实例变量 ,可以被类方法访问。

#import "Singleton.h"
static id instance = nil;

@implementation FKSingleton
+ (id) instance {
    // 如果instance为nil
    if (!instance) {
        // 创建一个Singleton实例,并将该实例赋给instance全局变量
        instance = [[super alloc] init];
    }
    return  instance;
}
@end

主函数:

int main(void) {
    @autoreleasepool {
        // 判断两次获取的实例是否相等,若相等则程序返回一
        NSLog(@"%d", [FKSingleton instance] == [FKSingleton instance]);
    }
}

在第一次调用类方法时,此时的全局变量值为id,进入if语句执行语句创建了一个实例对象,当第二次调用类方法时,全局变量已经不为空,而是第一次创建的对象,所以输出结果是1.
这里我们用到了关键字:super
1、直接调用父类中的某个方法
2、super处在对象方法中,那么就会调用父类的对象方法
super处在类方法中,那么就会调用父类的类方法
3、使用场合:子类重写父类的方法时想保留父类的一些行为

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值