OC源码中的一些宏

  • FOUNDATION_EXTERN
  #if define(__cplusplus)
  #define FOUNDATION_EXTERN extern "C"
  #else
  #define FOUNDATION_EXTERN extern
  #endif

表示extern全局变量,此时并没有分配内存,需要在.m文件中实现,为了支持C和C++混编(__cplusplus 是C++编译器内部定义的宏,在C++中,需要加extern “C”或包含在extern “C”块中),注意,此时外界是可以修改这个值.
用法如下

FOUNDATION_EXTERN NSString *name// h文件
const NSString *name = @"gitKong"; // m文件

extern的用法如下:
C++中extern用法
作用一:当它与”C”一起连用时,如extern “C” void fun(int a, int b);,则编译器在编译fun这个函数名时按C的规则去翻译相应的函数名而不是C++的。
作用二:当它不与”C”在一起修饰变量或函数时,如在头文件中,extern int g_nNum;,它的作用就是声明函数或变量的作用范围的关键字,其声明的函数和变量可以在本编译单元或其他编译单元中使用。
即B编译单元要引用A编译单元中定义的全局变量或函数时,B编译单元只要包含A编译单元的头文件即可,在编译阶段,B编译单元虽然找不到该函数或变量,但它不会报错,它会在链接时从A编译单元生成的目标代码中找到此函数
全局变量(extern)
有两个类都需要使用共同的变量,我们将这些变量定义为全局变量。比如,res.h和res.cpp分别来声明和定义全局变量,类ProducerThread和ConsumerThread来使用全局变量

/**********res.h声明全局变量************/ 
#pragma once 

#include <QSemaphore> 

const int g_nDataSize = 1000; // 生产者生产的总数据量 
const int g_nBufferSize = 500; // 环形缓冲区的大小 

extern char g_szBuffer[]; // 环形缓冲区 
extern QSemaphore g_qsemFreeBytes; // 控制环形缓冲区的空闲区(指生产者还没填充数据的区域,或者消费者已经读取过的区域) 
extern QSemaphore g_qsemUsedBytes; // 控制环形缓冲区中的使用区(指生产者已填充数据,但消费者没有读取的区域) 
/**************************/  

上述代码中g_nDataSize、g_nBufferSize为全局常量,其他为全局变量。

/**********res.cpp定义全局变量************/ 
#pragma once 
#include "res.h" 

// 定义全局变量 
char g_szBuffer[g_nBufferSize]; 
QSemaphore g_qsemFreeBytes(g_nBufferSize); 
QSemaphore g_qsemUsedBytes; 
/**************************/  

在其他编译单元中使用全局变量时只要包含其所在头文件即可。

/**********类ConsumerThread使用全局变量************/ 
#include "consumerthread.h" 
#include "res.h" 
#include <QDebug> 
ConsumerThread::ConsumerThread(QObject* parent) 
: QThread(parent) { 
} 
ConsumerThread::ConsumerThread() { 

} 
ConsumerThread::~ConsumerThread() { 
} 
void ConsumerThread::run() { 
 for (int i = 0; i < g_nDataSize; i++) { 
  g_qsemUsedBytes.acquire();
  qDebug()<<"Consumer "<<g_szBuffer[i % g_nBufferSize]; 
  g_szBuffer[i % g_nBufferSize] = ' '; 
  g_qsemFreeBytes.release(); 
 } 
 qDebug()<<"&&Consumer Over"; 
} 
/**************************/  

静态全局变量(static)
注意使用static修饰变量,就不能使用extern来修饰,即static和extern不可同时出现。
static修饰的全局变量的声明与定义同时进行,即当你在头文件中使用static声明了全局变量,同时它也被定义了。
static修饰的全局变量的作用域只能是本身的编译单元。在其他编译单元使用它时,只是简单的把其值复制给了其他编译单元,其他编译单元会另外开个内存保存它,在其他编译单元对它的修改并不影响本身在定义时的值。即在其他编译单元A使用它时,它所在的物理地址,和其他编译单元B使用它时,它所在的物理地址不一样,A和B对它所做的修改都不能传递给对方。
多个地方引用静态全局变量所在的头文件,不会出现重定义错误,因为在每个编译单元都对它开辟了额外的空间进行存储。
注:一般定义static 全局变量时,都把它放在.cpp文件中而不是.h文件中,这样就不会给其他编译单元造成不必要的信息污染。

  • NS_INLINE
#if !defined(NS_INLINE)
    #if defined(__GNUC__)
        #define NS_INLINE static __inline__ __attribute__((always_inline))
    #elif defined(__MWERKS__) || defined(__cplusplus)
        #define NS_INLINE static inline
    #elif defined(_MSC_VER)
        #define NS_INLINE static __inline
    #elif TARGET_OS_WIN32
        #define NS_INLINE static __inline__
    #endif
#endif

内联函数 inline static修饰,针对当前文件,兼容 win32,适配多个编译器环境( GNUC 是GCC编译器定义的一个宏;MWERKS 是Metrowerks C/C++编译器标识宏;_MSC_VER 是Microsoft Visual C++编译器标识宏,其中:inline 、 inline 、 inline 、__attribute((always_inline)) 只是不同编译器对应的keyword而已;GNU C的一大特色就是 attribute 机制。attribute 可以设置 函数属性、变量属性 和 类型属性;例如:函数声明中的 attribute((noreturn)) ,就是告诉编译器这个函数不会返回给调用者,以便编译器在优化时去掉不必要的函数返回代码)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值