1.const (常量)
const的作用和宏是很类似的,当有字符串常量的时候,苹果推荐我们使用const,苹果经常把常用字符串定义成const。
const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p,对象变量)
被const修饰的变量是只读的且是全局的。
const 与宏的区别
1.编译时刻 : const: 编译时刻 , 宏:预编译
2.编译检查: const 会检查错误 , 宏: 不会检查错误
3.宏的好处: 可以定义代码
4.宏的坏处: 编译时间过长, 因此常用的字符串通常使用 const修饰
注意:很多博客说宏使用的多了会造成内存不断增加,每次都会分配一个内存, 打印地址可以验证
const 作用:
1.仅仅是用来修饰右边的变量(只能修饰变量:基本变量,指针变量,对象变量)
2.const修饰的变量表示只读
int * const p; // p:只读 *p:变量
const int *p1; // *p1:只读 p1:变量
int const *p2; // *p2:只读 p2:变量
int const * const p3; // *p3:只读 p3:只读
const int * const p4; // *p4:只读 p4:只读
2.static
static作用
1.修饰局部变量
* 延长这个局部变量的生命周期,只要成员运行,局部变量就会一直存在
* 局部变量只会分配一次内存,为什么?用 static修饰的代码,只会在程序一启动,就会执行,以后就不会再执行
2.修饰全局变量
* 只会修改全局变量的作用域,表示会只能是当前文件使用
static修饰变量注意点
用于定义一个内部全局变量
为了提高数据的安全性, 不让别人在其它文件中修改我们的全局变量
只要用static修改的全局变量就是内部全局变量, 只能在当前文件中使用
如果多个文件中存在同名的内部全局变量, 相互不会影响
如果既有外部全局变量也有内部全局变量, 那么会优先访问内部全局变量
3.extern
作用:
extern主要是用来引用全局变量,它的原理就是先在本文件中查找,本文件中查找不到再到其他文件中查找。
用于声明一个外部全局变量,声明变量是其他文件的外部变量。
不能定义变量
声明只需要在使用变量之前声明就可以了
声明和定义的区别:(声明不会开辟存储空间,定义会开辟存储空间)
注意:UIKIT_EXTERN == extern
总结:
-
在iOS开发中请尽量多使用const、enum来代替宏定义(#define),随着项目工程的逐渐增大,过多的宏定义还可能影响项目的编译速度。
-
为何不将上面常量直接导入pch文件?
苹果不建议使用pch,pch的原理是将其中定义的宏或全局常量/变量等copy到每个执行文件(.m文件), 如果在其中定义全局常量, 则会报重复定义全局常量错误. -
iOS项目中经常会用到一些常量字符串,如果单独的在一个.m中使用,可以用宏定义,可以用static + const 来规定一个字符串,比如最常用的cell的reuserID,一般我们很少会用到宏来修饰,因为宏不做检查,不会报编译错误,而且预编译的时候,会延长编译时间,苹果也不推荐我们大量的使用宏。
-
查阅到很多第三方库和类似的苹果的用法,可以看到,很多加以区分的const字符串都会写到一个专门使用的类中,比如MJRefresh的MJRefreshConst.h 和 MJRefreshConst.m,这种写法有很多好处,其中之一就是:在规定全局变量,并且在其他地方引用的时候,容易造成字符串重复的问题,特别是在协同开发的过程中。因此,管理人员都是会规定好一个类来专门的管理这些 只读字符串 ,也就是MJRefreshConst 或者是上面的Const,这样的话,在引用过程中,直接import这个类就可以使用了,避免了很多不必要的麻烦。
使用注释加以区分的话,能够把这些字符串分类管理,更加提高团队工作效率。
用法总结:
1. 在函数外,直接定义对象,不需要额外添加修饰符,对象可被修改; 一般形式的全局变量
2. 只用static修饰,对象可以被修改,但是生命周期在APP运行期; 用static修饰就是静态变量(也叫全局静态变量),不用static修饰的就是全局非静态变量;
修饰局部变量:让局部变量只初始化一次;局部变量在程序中只有一份内存;并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,这个局部变量才会销毁)
修饰全局变量:全局变量的作用域仅限于当前文件
3. 用const修饰:一般不定义在本文件内,字符串可以被修改,也可以不被修改(主要);用const修饰的就是常量;全局非静态/静态常量
4. 用static,const一起修饰:全局静态常量,在本文件内字符串可以被修改,也可以不被修改(主要);
常用的三种:
1. static 修饰全局静态变量,比如cell的标识符
2. static+const在本文件内使用,修饰不可变字符串,全局静态常量
3. const在单独一个文件内使用,修饰字符串,变成不可变的常量。
*/
4. 宏
宏的常见用法(常见字符串抽成宏,常见代码抽成宏)当有字符串常量的时候,苹果推荐我们使用const,苹果经常把常用字符串定义成const
宏与const的区别:
编译时刻:宏是预编译(编译之前处理),const是编译阶段。
编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。
宏的好处:宏能定义一些函数,方法。 const不能。
宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。
注意:swift中, 苹果已经将宏杀掉, 所以项目开发中, 须用const代替宏.
宏定义:
//注意:
//1.宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串。
//2.带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。并且计算结果最好也括起来防止错误。
#define NAME @"henry" //不带参数的宏定义 (格式: #define 标示符 字符串(“字符串”可以是常数、表达式、格式串等。)宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令。)
#define average(a, b) (a+b)/2 //带参数的宏定义:(对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。格式:#define 宏名(形参表) 字符串)
//条件编译后面的条件表达式中不能识别变量,它里面只能识别常量和宏定义
#define SCORE 67
#if SCORE > 90
//("优秀\n");
#elif SCORE > 60
//NSLog("良好\n");
#else
//NSLog("不及格\n");
#endif
#ifdef MACRO_Define // 如果已定义MACRO_Define这个宏
//代码块1
#else
//代码块2
#endif
5. 结构体,枚举(typeof与typedef)
typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。可以理解为:我们根据typeof()括号里面的变量,自动识别变量类型并返回该类型。
typeof 常见运用于Block中,避免循环引用发生的问题。
用法:
//定义一个和self相同数据类型的bself ,并赋值为self,在block中使用
__weak typeof (self) weakSelf = self;
注意: typeof 括号中的值和等于后面的值是相同的类型。
__weak typeof(self.contentView) ws = self.contentView;
typedef:定义一种类型的别名,而不只是简单的宏替换。
typedef 常用于命名(枚举和Block)
用法1-结构体
//结构体
typedef struct Myrect {
float width;
float height;
}myRect;
用法2-枚举
//枚举值 它是一个整形(int) 并且,它不参与内存的占用和释放,枚举定义变量即可直接使用,不用初始化.
//在代码中使用枚举的目的只有一个,那就是增加代码的可读性.
typedef NS_ENUM (NSUInteger,direction){
left=0,
right=1,
top =2,
down =3
};
typedef NS_ENUM (NSUInteger,direction_2){
left2 = 0,
right2 = 1 << 0,
top2 = 1 << 1,
down2 = 1 << 2
};
用法3-Block
//1.重新起个名字
typedef void(^PassValueBlock)(NSString *);
@interface BlockViewController : BaseViewController
//2.声明block属性
@property(nonatomic,copy)PassValueBlock passValueBlock;
网友评论