前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS不可错过的关键字

iOS不可错过的关键字

作者头像
Dwyane
发布2018-09-30 10:36:30
3560
发布2018-09-30 10:36:30
举报
文章被收录于专栏:技术总结技术总结

建议查看原文:https://cloud.tencent.com/developer/article/1350636(不定时更新)

本文概览

前言:我们看源码,或者面试经常遇到一些关键字,又由于网上的相关文章部分观点错误,我在此汇总了我之前的笔记以及查阅相关书籍,站在巨人的肩膀上,整合出此篇文章。

总之,为了提升,为了面试,了解这些关键字,非常有必要。每个观点,我尽可能的结合代码讲解。

extern

当编译器遇到extern模板声明时,它不会在本文件中生成实例化代码,将一个实例化声明为extern就表示承诺在程序的其他位置有该实例化的一个非extern定义。对于一个给定的实例化版本,可能有多个extern声明,但必须只有一个定义。

1、在其他文件(DWConst)的实现文件声明变量

代码语言:javascript
复制
// DWConst.m
// 定义了整个程序都能访问的常量
const NSString *myExtern = @"abc";
@implementation DWConst

@end

2、在 ViewController类赋值并打印(不用导入DWConst.h)

代码语言:javascript
复制
// ViewController.m
    NSLog(@"myExtern=%@", myExtern);
    NSLog(@"myExtern 地址=%p", &myExtern);
    myExtern = @"hello";
    NSLog(@"myExtern=%@", myExtern);
    NSLog(@"重新赋值后的myExtern 地址=%p", &myExtern);

打印: myExtern=abc myExtern 地址=0x108aaf180 myExtern=hello 重新赋值后的myExtern 地址=0x108aaf180

定义后,无论后面怎样使用,都只是共用一个内存地址(看上面打印),也表明任意一处改变值,都会影响其他处。

static

1、修饰全局变量
  • 全局变量的作用域仅限于当前文件(限制作用域)
2、修饰局部变量(下面3个作用,自我觉得,实质是一样的)
  • 保证只会开辟一个内存
  • 只会初始化一次
  • 没有改变局部变量的作用域,仅仅是改变了局部变量的生命周期(直到程序结束,这个局部变量才会销毁)
代码语言:javascript
复制
- (void)viewDidLoad {
    NSLog(@"----------------- ViewDidLoad -----------------");
    [self testStatic];
}
// 已省略按钮创建代码
- (void)btnClicked {
    NSLog(@"----------------- btnClicked -----------------");
    [self testStatic];
}

- (void)testStatic {
    NSInteger i = 0;
    i++;
    static NSInteger staticValue = 0;
    staticValue++;
    NSLog(@"i的地址=%p,staticValue的地址=%p", &i, &staticValue);
}

打印: ----------------- ViewDidLoad ----------------- i的地址=0x7ffee2200948,staticValue的地址=0x10d9ff1c8 ----------------- btnClicked ----------------- i的地址=0x7ffee2200fd8,staticValue的地址=0x10d9ff1c8

由此看出,staticValue 的地址没有变,证明了 ”保证只会开辟一个内存“

NSLog(@"i的地址=%p,staticValue的地址=%p", &i, &staticValue); 替换成

NSLog(@"i = %ld, s.value = %ld", (long)i, (long)staticValue);

打印: ----------------- ViewDidLoad ----------------- i = 1, s.value = 1 ----------------- btnClicked ----------------- i = 1, s.value = 2

由此看出,staticValue 的有 +1,而 i 永远都是 1,证明了 static 关键字修饰局部变量”延长了声明周期“,因为 i 没修饰,则每次都重新创建,再 +1

const

至于 const ,我先给出例子:

代码语言:javascript
复制
    const int *p = NULL;
    *p = 20; // 报错

*p 会报错 ,被 const 修饰的 *p 只能被赋值一次, 再次赋值,就会报错 “Read-only variable is not assignable”

代码语言:javascript
复制
    int a = 10;
    p = &a; // 正常通过
    NSLog(@"*p=%d", *p);
    NSLog(@"p=%p", p);

打印: *p=10 p=0x7ffeec2a9a04

代码语言:javascript
复制
    int * const p1 = NULL;
    NSLog(@"p1=%p", p1);
    *p1 = 30; // 编译通过,但运行报错

看清楚!p 还是可以修改的,不同于 *p 。因为 const 修饰的是 *p ,而不是 p

*p 和 p 的区别:

*p 是存储的值,而 p 是指针。上例中,p 指针,则存储着 a 的内存地址,而 *p 等于10。

同样,在 id 类型的运用

代码语言:javascript
复制
    NSString * const city = @"CN";
    city = @"US"; // 报错,

const 修饰的 city 为只读属性

static 和 const 的配合

1、使用
代码语言:javascript
复制
static const CGFloat Height = 180;
static const CGFloat author = @"Dwyane";
2、与 #define 的对比
  • 共同点:一旦定义,都不允许修改
  • 不同点:static const修饰变量只有一份内存,检查数据类型;#define仅仅简单文字替换,不会检查类型,每次使用都需要创建一份内存

inline 内联函数

1、使用
代码语言:javascript
复制
static inline int DWMax(int x, int y) {
    return (x > y)? x : y;
}
- (void)viewDidLoad {
      int i = DWMax(20, 30);
      NSLog(@"max = %d", i);
}

普通函数的好处与缺点

2、引入内联函数的目的

对于一些函数体代码不是很大,但又频繁地被调用的函数来讲,解决其效率问题更为重要。引入内联函数实际上就是为了解决这一问题。

3、滥用内联函数的弊端

滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快。

注意:内联函数只是我们向编译器提供的申请,编译器不一定采取inline形式调用函数.另外,如果不申请,编译器会选择性的自动会汇编成内联函数

结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用! 另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行). -->参考

inline 函数与 #define 比较

建议也看宏与普通函数的区别

inline 函数与 #define 区别: 1、 宏调用并不执行类型检查,甚至连正常参数也不检查,但是函数调用却要检查。 2、 C语言的宏使用的是文本替换,可能导致无法预料的后果,因为需要重新计算参数和操作顺序。 3、 许多结构体使用宏或者使用不同的语法来表达很难理解。内联函数使用与普通函数相同的语言,可以随意的内联和不内联。 4、 内联代码的调试信息通常比扩展的宏代码更有用。




Static参考

内联函数的参考

iOS OC内联函数 inline

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.09.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • extern
  • static
    • 1、修饰全局变量
      • 2、修饰局部变量(下面3个作用,自我觉得,实质是一样的)
      • const
      • static 和 const 的配合
        • 1、使用
          • 2、与 #define 的对比
          • inline 内联函数
            • 1、使用
              • 2、引入内联函数的目的
                • 3、滥用内联函数的弊端
                • inline 函数与 #define 比较
                相关产品与服务
                对象存储
                对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档