一、成员变量(属性),局部变量,全局变量
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中打开”,就可以点赞咯~
到此为止.记录下容易忘的细节同大家分享!!!🙂🙂🙂