iOS 关键字 - AlvinSunny/OC-TheUnderlying GitHub Wiki

常用关键字理解

strongcopyweakassign

strong修饰的对象是强引用,该指针指向的对象引用计数会加1

copy修饰的对象一般为不可变数据类型,可以保证修改副本对象不影响原对象

weak修饰的对象时弱引用,该指针指向的对象引用计数不会加1

assign修饰基本数据类型如Int、CGRect、NSInteger、CGFloat、CGSize、CGSize、CGPoint等

assign不用来修饰OC是因为其不安全,不能指向的对象销毁时把指针置空;而被weak可以

nonatomicatomic

nonatomic:非原子性,不会对赋值和取值过程加锁

atomic:原子性,会对赋值和取值过程加锁

atomic加锁逻辑自iOS10之后从自旋锁变为互斥锁;

atomic加锁原理:创建一个PropertyLocks(锁缓存池),通过传入标识(self+偏移地址)锁定唯一属性的方式做到setter和getter方法同时只能有一个进行,保证安全

@synthesize 和 @dynamic的区别

  • @property 会自动合成成员变量,有两个对应的修饰符,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;
  • @synthesize的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
  • @dynamic告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
// 如果指定了成员变量的名称,会生成一个指定名称的成员变量
@synthesize firstName = _myFirstName;

在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
回答这个问题前,我们要搞清楚一个问题,什么情况下不会自动合成成员变量?

1)同时重写了 setter 和 getter 时
2)重写了只读属性的 getter 时
3)使用了 @dynamic 时
4)在 @protocol 中定义的所有属性
5)在 category 中定义的所有属性
6)重载的属性

externstatic的区别

全局变量分两种:外部变量、内部变量

外部变量:定义的变量能被本文件和其他文件访问

  • 默认情况下,所有的全局变量都是外部变量
  • 不同文件中的同名外部变量都代表同一个变量
定义一个外部变量
 int a ;

声明一个外部变量
extern int a ;

内部变量:定义的变量只能被本文件访问,不能被其他文件访问

  • 不同文件中的同名内部变量,互不影响
定义一个内部变量
static int a ;

static 对变量的作用:定义一个内部变量

extern 对变量的作用:声明一个外部变量

static对函数的作用:定义和声明一个内部函数

extern对函数的作用:定义和声明一个外部函数(可以省略不写)

const的用法 ? 作用是什么 ?

1.用法:被用来修饰基本数据类型或指针

2.作用:被修饰的类型访问权限会变为只读


修饰基本数据类型时,基本数据类型只能被赋值一次
int const a = 1;
const int b = 2;

a = 3; //Xcode提示错误,无法修改a的值
b = 3; //Xcode提示错误,无法修改b的值

const在指针符号(*)的左边: *p指向的内存中的值为只读(int const *p和const int *p效果一致)

int a = 1;
int b = 2;
int const *p = &a; //*p访问的是a变量的值
*p = 30;  //Xcode提示错误,无法修改
p = &b; 

const在指针符号(*)的右边 : p指针中保存的内存地址为只读

int a = 1;
int b = 2;
int *const p = &a;
*p = 30; 
p = &b; //Xcode提示错误,无法修改

const同时在指针符号(*)两边 : 指针指向的地址不可以改变,同时无法改变指向地址所保存的值。

int a = 1;
int b = 2;
int const * const p = &a;
*p = 30; //Xcode提示错误,无法修改
p = &b; //Xcode提示错误,无法修改

补充:static可以多次赋值,但最好不要那么做,负责会失去静态变量的意义

@private、@protected、@public、@package

@private 私有的

代表私有,也就是只有自己有,别人谁都不可用,不不可以继承的。

@protected 受保护的

相较上边的private而言,就没有那么自私了,他自己可以用,自己的子类也是可以共享的,是可以继承的.

@public 公共的

相较上边而言,谁都可以用,只要你有这个类的对象,就可以拿到public下的变量,

@package

这个主要是用于框架类,使用@private太限制,使用@protected或者@public又太开放,就使用这个package吧。