美文网首页
OC 中定义属性(成员变量)及相关修饰符、关键字

OC 中定义属性(成员变量)及相关修饰符、关键字

作者: 楚简约 | 来源:发表于2017-04-24 17:06 被阅读0次

一、成员变量(属性),局部变量,全局变量

1.成员变量

概念: 写在类声明@interface...{}的大括号中的变量, 称之为成员变量(属性, 实例变量)

使用方式: 成员变量只能通过对象来访问

定义与初始化: 成员变量不能在定义的同时进行初始化, 注意:成员变量不能离开类, 离开类之后就不是成员变量

存储与释放: 存储在堆(当前对象对应的堆的存储空间中), 存储在堆中的数据, 不会被自动释放, 只能程序员手动释放

而在这个地方,其实也要区分一下成员变量和属性

成员变量就是我们在开发中,类似下面这样定义的变量,例如:

@interface Person : NSObject
{
    @public
    NSString *_name;
    CGFloat _age;
}
@end

这里又要解释一下概念

指令 ----- 意思
@private --- 作用范围只能在自身类
@protected --- 作用范围在自身类和继承自己的子类,什么都不写,默认是此属性。
@public --- 作用范围最大,在任何地方
@package ---只要处在同一个框架中,就能直接访问对象的成员变量

则_name,_age便是成员变量。

属性就是在开发中,我们用 @property 关键字声明的变量,如:

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) CGFloat *age;

该方法做了三件事情
①自动生成_name和_age成员变量,
②自动生成相应的getter方法
③自动生成相应的setter方法

因此两者最直观的区别是属性会有相应的getter方法和setter方法,而成员变量没有,另外,外部访问属性可以用"."来访问,访问成员变量需要用"->"来访问

而成员变量想自动生成相应的getter/setter方法,可以用@synthesize修饰解决

synthesize定义方法 -> m文件中实现getter和setter方法。
@interface 类名 (){
    @public
    CGFloat _age;
}  
@end

@implementation 类名
@synthesize age = _age;
@synthesize age ;  (或者这样写)

当然,自从xcode4.4之后,@property方法生成的getter方法和setter方法可能满足不了您的需求,您也可以自己手动添加getter方法和setter方法,如果手动写了setter方法@property就不会生成setter方法,但还是会生成getter方法,getter同理,如果您将setter方法,getter方法都进行手动书写了,@property将不会为您生成相应的getter方法和setter方法。

2.局部变量

概念: 写在函数或者代码块中的变量, 称之为局部变量

作用域: 从定义的那一行开始, 一直到遇到大括号或者return

定义与初始化: 局部变量可以先定义再初始化, 也可以定义的同时初始化

存储与释放: 存储在栈, 存储在栈中的数据有一个特点, 系统会自动释放

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSString *partner = @"";
    UIImage *img = [UIImage imageNamed:@""];
    UIButton *btn = [UIButton new];
    NSArray *arr = [NSArray array];
}
//这些变量只在该方法中存在, 在 } 之后会自动释放

3.全局变量

概念: 写在函数和大括号外部的变量, 称之为全局变量

作用域: 从定义的那一行开始, 一直到文件末尾

定义与初始化: 全局变量可以先定义再初始化, 也可以定义的同时初始化

存储与释放: 存储在静态区, 程序一启动就会分配存储空间, 直到程序结束才会释放

@implementation 类名
static NSString *const cellID = @"lookDoctorCell";

二.定义属性括号中关键字

readonly: 只读特性, 只会生成getter方法, 只可被外界读取, 不能修改
readwrite: 可读可写特性, 需要生成setter和getter方法时使用, 可被外界读取和修改.


atomic: 会给属性加上一个同步锁, 这是为了防止多线程同时访问属性出现异常需要添加的属性, 但是这样会增加额外的内存开销 并且在变编程习惯中, 我们都应该避免多线程访问统一资源. 即便是使用atomic, 在多线程时也无法完全保证线程安全, 往往是需要手动添加线程锁
nonatomic: 非原子性, 即非线程安全的, 不给变量提供线程锁保护, 这样会提高性能(推荐使用)


assign:适用于基本数据类型
assign:对象不能使用 assign,但原始类型(BOOL、int、float)仍然可以使用
weak:是适用于NSObject对象,并且是一个弱引用。
weak当对象销毁的时候,指针会被自动设置为nil,而assign不会* assigin 可以用非OC对象,而weak必须用于OC对象


copy: 对于字符串和block的属性一般使用copy
和之前MRC的 copy 一样,复制一个对象并创建 strong 关联
strong: 等同于MRC的"retain",属性成为对象的拥有者


说一下@property 括号里面没有这个关键字
对应基本数据类型默认关键字是
property的属性默认是:readwrite,assign, atomic
在ARC内存管理模式下,对于普通的OC对象
property的属性默认是:readwrite,strong, atomic

@property (nonatomic)    int             isIndex;  
@property (nonatomic)    BOOL       isNotDex;
@property (nonatomic)    NSString  * str;
//等同于
@property (nonatomic, readwrite , assign)    int             isIndex;  
@property (nonatomic, readwrite , assign)    BOOL       isNotDex;
@property (nonatomic, readwrite , strong)    NSString  * str;

下面列举常用属性定义

@property (nonatomic , assign) int  isIndex;  
@property (nonatomic , assign) BOOL    isOK;
@property (nonatomic , assign) float   keyNum;
@property (nonatomic, strong) NSIndexPath * selectedIndex;
@property (nonatomic , strong) UITableView * cityView;
@property (nonatomic, strong) NSArray * countryArray;
@property (nonatomic, strong) NSDictionary * allData;
@property (nonatomic ,weak)IBOutlet UITableView * TableView;  ///xib
@property (nonatomic ,weak) IBOutlet NSLayoutConstraint *bottomViewHeightConstraint;///xib
关于block 属性
首先,定义block
typedef void (^BLWebViewProgressBlock)(float progress);
然后,定义类的block属性
@property (nonatomic, copy) BLWebViewProgressBlock progressBlock;

我是楚简约,感谢您的阅读,

喜欢就点个赞呗,“❤喜欢”,

鼓励又不花钱,你在看,我就继续写~

非简书用户,可以点右上角的三个“...”,然后"在Safari中打开”,就可以点赞咯~


到此为止.记录下容易忘的细节同大家分享!!!🙂🙂🙂

相关文章

网友评论

      本文标题:OC 中定义属性(成员变量)及相关修饰符、关键字

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