经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
ios宏定义学习
来源:cnblogs  作者:久依  时间:2019/2/19 9:25:59  对本文有异议
宏简介:

宏是一种批量处理的称谓。一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。这种替换在预编译时进行,称作宏展开。编译器会在编译前扫描代码,如果遇到我们已经定义好的宏那么就会进行代码替换,宏只会在内存中copy一份,然后全局替换,宏一般分为对象宏和函数宏(下面会详细介绍)。

宏的弊端:

如果代码中大量的使用宏会是的编译时间变长。

对象宏:

像这样:#define M_PI 3.14159265358979323846264338327950288
这个没什么好讲的,我想只要是个iOS程序员就都会用。
下面附送一波我们在工程中常用的宏

  1. //获取屏幕的宽和高
  2. #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
  3. #define SCREENH_HEIGHT [UIScreen mainScreen].bounds.size.height
  4. //设置随机颜色
  5. #define LRRandomColor [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0]
  6. //设置RGB和RGB颜色
  7. #define LRRGBColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
  8. #define LRRGBAColor(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(r)/255.0 blue:(r)/255.0 alpha:a]
  9. // clear背景颜色
  10. #define LRClearColor [UIColor clearColor]
  11.  
  12. //判断是否为iPhone
  13. #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
  14. //判断是否为iPad
  15. #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
  16. //判断是否为ipod
  17. #define IS_IPOD ([[[UIDevice currentDevice] model] isEqualToString:@"iPod touch"])
  18. // 判断是否为 iPhone 5SE
  19. #define iPhone5SE [[UIScreen mainScreen] bounds].size.width == 320.0f && [[UIScreen mainScreen] bounds].size.height == 568.0f
  20. // 判断是否为iPhone 6/6s
  21. #define iPhone6_6s [[UIScreen mainScreen] bounds].size.width == 375.0f && [[UIScreen mainScreen] bounds].size.height == 667.0f
  22. // 判断是否为iPhone 6Plus/6sPlus
  23. #define iPhone6Plus_6sPlus [[UIScreen mainScreen] bounds].size.width == 414.0f && [[UIScreen mainScreen] bounds].size.height == 736.0f
  24. //获取系统版本
  25. #define IOS_SYSTEM_VERSION [[[UIDevice currentDevice] systemVersion] floatValue]
  26. //判断 iOS 8 或更高的系统版本
  27. #define IOS_VERSION_8_OR_LATER (([[[UIDevice currentDevice] systemVersion] floatValue] >=8.0)? (YES):(NO))
  28. //判断是真机还是模拟器
  29. #if TARGET_OS_IPHONE
  30. //iPhone Device
  31. #endif
  32. #if TARGET_IPHONE_SIMULATOR
  33. //iPhone Simulator
  34. #endif
  35.  
  36. //沙盒目录文件
  37. //获取temp
  38. #define kPathTemp NSTemporaryDirectory()
  39. //获取沙盒 Document
  40. #define kPathDocument [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
  41. //获取沙盒 Cache
  42. #define kPathCache [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]
  43.  
  44. //NSLog
  45. #define NSLog(format, ...) do { \
  46. fprintf(stderr, "<%s : %d> %s\n", [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, __func__); (NSLog)((format), ##__VA_ARGS__); fprintf(stderr, "-------\n"); } while (0)
函数宏:

其实说到宏那么不得不提的就是在宏中常用的预处理命令和运算符

指令及作用:

  1. #空指令,无任何效果
  2. #define定义宏
  3. #undef取消已定义的宏
  4. #if如果给定条件为真,则编译下面代码
  5. #ifdef如果宏已经定义,则编译下面代码
  6. #ifndef如果宏没有定义,则编译下面代码
  7. #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
  8. #endif结束一个#if……#else条件编译块
  9. #error停止编译并显示错误信息

#运算符:
例如: #define demo1(n) "123"#n
出现在宏定义中的#运算符把跟在其后的参数转换成一个字符串。有时把这种用法的#称为字符串化运算符

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. NSLog(@"%s",demo1(abc));
  4. }
  5. //打印会输出 123abc

##运算符:
例如:#define demo2(m,n,j) m##n##j
##运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. NSLog(@"%d",demo2(1, 2, 3));
  4. }
  5. //打印会输出 123

举例:

  1. //宏定义
  2. #ifndef weakify
  3. #define weakify(o) __weak typeof(o) weak##o = o;
  4. #define strongify(o) __strong typeof(o) o = weak##o;
  5. #endif
  1. //调用
  2. -(void)demo2
  3. {
  4. weakify(_v2)
  5. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  6. NSInteger count =0;
  7. strongify(_v2)
  8. while( count<10) {
  9. count++;
  10. NSLog(@"---------%@---%ld",weak_v2,(long)count);
  11. sleep(1);
  12. }
  13. });
  14. //3秒后将 self.v2对象 销毁
  15. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
  16. self.v2=nil;
  17. });
  18. }
上面定义了两个宏,第一个相当于实现了__weak typeof(self) weakself = self;用##把weak和self连接起来,实现了self对block的弱引用,第二个宏的作用是保护block里的__weakself防止self被释放后block里的 __weakself也被释放(如果block在栈区,会将block copy一份到堆区,如果block在堆区,就在copy一份在堆区,此时block的引用计数为2)。
在上面demo2中_v2是当前类的属性,在并发队列线程的block中用strongify保护起来,在3秒后self.v2释放,但由于self.v2被copy一份到堆区,所以依然可以打印_v2。

 


 



原文链接:http://www.cnblogs.com/jiuyi/p/10397464.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号