美文网首页
基础:记录iOS中的各种变量区分

基础:记录iOS中的各种变量区分

作者: 喔牛慢慢爬 | 来源:发表于2021-03-11 13:46 被阅读0次

    OC中都有哪些变量呢?

    OC中有许多变量类型,在这里简单的记录下这些变量的定义和区别。常用的变量有:成员变量、实例变量、全局变量、局部变量、静态变量、属性变量。

    一、成员变量和实例变量

    成员变量中包括实例变量(对象类型变量)和基础数据类型变量,实例变量是由类定义声明的对象。

    1. 声明位置:
      成员变量被声明在.h头文件的@interface className : NSObject@end之间的大括号之间或在.m文件的类扩展中声明。
    @interface Test : NSObject
    {
        //声明成员变量,默认访问权限修饰词是protected
        NSString *name;  //实例变量
        NSString *city; //实例变量
        NSString *country; //实例变量
        int age;  // 基础数据类型变量
    }
    @end
    
    1. 作用域
    • 成员变量声明在.m文件时:只有本文件内部可以访问;
    • 成员变量声明在.文h件时: 其作用于由成员变量的访问权限修饰词控制;
    • @public:公开的
      实例变量可以在项目中的任何地方被访问
    • @ protected:受保护的
      实例变量只可以在当前类或其子类的对象方法中被访问,默认的访问权限修饰符。
    • @private:私有的
      实例变量只可以在当前类的对象方法中被访问
    • @package:整个包,框架级别
      整个项目中都可以访问,作用域介于私有和公开之间,只要处于同一个框架中相当于@public,在框架外部相当于@private

    代码:

    #import "ViewController.h"
    #import "Test.h"
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        Test *test = [[Test alloc] init];
        //当Test的country成员变量访问权限未public时,此时可以通过->访问country
        NSLog(@"%@",test->country);
    }
    @end
    //Test类
    #import <Foundation/Foundation.h>
    @interface Test : NSObject
    {
        @public
        NSString *name;
        NSString *city;
        NSString *country;
        int age;
    }
    @end
    
    修饰符 类型 继承 子类访问 外部访问
    @private 私有 不可继承 不可以 不可以
    @public 共有 可继承 可以 可以
    @protected 保护 可继承 可以 不可以

    注意:不建议使用test->country这种方式来访问使用@public修饰的成员变量,因为这样是不安全的。所以建议手动添加自定义成员变量的get/set方法;

    代码:

    //Test类
    #import <Foundation/Foundation.h>
    @interface Test : NSObject
    {
        @public
        NSString *name;
        NSString *city;
        NSString *country;
        int age;
    }
    -(NSString *)getName;
    -(void)setName:(NSString *)name;
    @end
    //test.m中
    -(NSString *)getName {
        return name;
    }
    -(void)setName:(NSString *)newName {
        name = newName;
    }
    
    1. 特点
    • 访问必须通过实例对象来访问,不能脱离类;
    • 声明和初始化是分开的,声明实例变量的时候无法初始化赋值;
      +成员变量存储在当前对象对应的堆的存储空间中,不会被自动释放,只能手动释放;

    二、属性变量

    在OC中用@property来声明一个属性,编译器会自动为实例变量生产setter和getter方法。声明属性时会默认创建格式为“_className”的成员变量。属性简化了我们为成员变量实现set/get方法的操作,属性专用于从类外部对变量进行调用和赋值。

    1. 声明位置:
      可以声明在.h头文件的@interface className : NSObject和@end之间或在.m文件的类扩展的大括号外面声明。
    2. 作用域
    • 声明在.m文件时:只有本文件内部可以访问;
    • 声明在.文h件时: 在引用当前类的的文件中可以访问;
    1. @synthesize和@dynamic
    • @synthesize

    表示告诉编译器自动实现成员变量的getter/setter方法,并将存取方法作用于系统根据属性名创建的“_className”变量。

    • @dynamic

    表示告诉编译器不需要自动生产getter/setter方法,由开发者手动实现getter/setter。

    1. @property修饰符
    • 原子性/非原子性:
    • 属性默认是atomic原子性的,表示只有一个线程访问变量,原子性影响效率。
    • 属性设置nonatomic可以使用多个线程访问变量,优点效率快,大部分情况下使用非原子性 nonatomic。
    • 读写属性修饰符:
    • readonly只读属性,只生成getter方法,不会生成setter方法。
    • readwrite读写属性,生产getter和setter方法,属性默认readwrite。
    • 设置setter/getter别名:
    • getter = 设置getter新的别名;
    • setter = 设置setter新的别名;
    1. 内存管理
    • assign:
      默认值,主要用于简单的基础数据类型,例如int、float等,用于直接赋值,不做任何内存管理。
    • strong:
      在ARC环境下使用,表示强引用指针,相当于retain,其修饰的对象引用计数会增加1,该对象只要引用计数不为0则不会被销毁。
    • weak:
      在ARC环境下使用,表示弱引用指针,weak修饰的对象在释放后,指针地址会被置为nil。
    • copy:
      对原有对象进行拷贝,复制每次都会在内存中拷贝一份对象,指针指向不同地址,一般用在修饰有可变对应类型的不可变对象上,如NSString, NSArray, NSDictionary。
    • retain:
      会自动帮我们生成getter/setter方法内存管理的代码,在setter方法中,对传入的对象进行引用计数加1的操作,一般用于对象的修饰。

    三、全局变量

    定义在函数外或大括号外声明定义的变量,全局变量存储在内存的全局(静态)存储区,程序启动时就会分配存储空间,直到程序结束才会被释放。可以跨文件访问

    1. 声明位置
      在OC中可以声明在.h或.m文件的函数外部。
    2. 作用域
      全局变量的作用域是整个程序源。

    四、静态变量

    可以声明在函数外,也可声明在函数或代码块内部。

    • 当声明在函数外部时就是使用static关键字将全局变量变为静态全局变量,改变了全局变量的作用域:只限于声明静态全局变量的整个文件访问使用。
    • 当声明在函数或代码块内部时,被称为静态局部变量,其存储区域也是在全局(静态)存储区。静态局部变量的生命周期是整个程序源,但它的作用域只在代码块内。

    注意:1、存储在静态存储区的变量,其内存会直到程序结束才会被销毁,即生命周期是整个程序;2、当静态全局变量声明在.h头文件时,其他类引用静态全局变量所在类头文件后可以访问。

    五、局部变量

    局部变量也称作自动变量,需要在函数内部声明,在内存中存储在栈区stack。并当函数结束后释放内存,局部变量也会被销毁。

    相关文章

      网友评论

          本文标题:基础:记录iOS中的各种变量区分

          本文链接:https://www.haomeiwen.com/subject/ofksfltx.html