OC中一些预定义宏

作者: 大刘 | 来源:发表于2022-06-26 22:14 被阅读0次

    Created by 大刘 liuxing8807@126.com

    看一些内置的宏(C/C++, OC可用),比如:

    __LINE__     是整数类型;
    __FILE__     宏是字符串类型;
    __TIME__     宏是字符串类型;
    __FUNCTION__ 宏是字符串类型;
    __DATE__     宏是字符串类型;
    

    采用#define定义宏,宏的优劣很明显,但使用宏在某些场景下确实可以起到一些作用;

    举其中的一些示例:

    __FUNCTION__

    C语言中获取函数名,一般是__func__,GCC还支持FUNCTION.同时,PRETTY_FUNCTION`对函数的打印会带上参数

    #include <stdio.h>
    
    void sayHello(char *str) {
        printf("%s: hello %s\n", __PRETTY_FUNCTION__, str); // void sayHello(char *): hello daliu
    }
    
    int main(int argc, const char * argv[]) {
        printf("%s %s %s\r\n",__func__,__FUNCTION__,__PRETTY_FUNCTION__); // main main int main(int, const char **)
        sayHello("daliu");
        return 0;
    }
    

    __COUNTER__

    __COUNTER__也是C的一个宏,它的值从0开始,每次调用就会加1,因为一般可以用来做为UniqueId的一部分.

    From Doc:

    COUNTER
    This macro expands to sequential integral values starting from 0. In conjunction with the ## operator, this provides a convenient means to generate unique identifiers. Care must be taken to ensure that COUNTER is not expanded prior to inclusion of precompiled headers which use it. Otherwise, the precompiled headers will not be used.

    上面讲通常搭配连接符##使用,示例:

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    #define ZZ_CONCAT(A, B) ZZ_CONCAT2(A, B)
    #define ZZ_CONCAT2(A, B) A##B
    
    #define SKILL \
    + (void)ZZ_CONCAT(skill_, __COUNTER__) { \
        NSLog(@"%@", NSStringFromSelector(_cmd)); \
    }
    
    @interface Person : NSObject
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "Person.h"
    #import <objc/runtime.h>
    
    @implementation Person
    
    + (void)load {
        [self printClassMethod:self];
    }
    
    // 打印类方法
    + (void)printClassMethod:(Class)cls {
        unsigned int methodCount = 0;
        // object_getClass(cls) 获取元类对象,类方法存储在元类对象中
        Method *methods = class_copyMethodList(object_getClass(cls), &methodCount);
    
        for (unsigned int i = 0; i < methodCount; i++) {
            Method method = methods[i];
            NSString *methodName = NSStringFromSelector(method_getName(method));
            NSLog(@"方法名: %@", methodName);
        }
    
        free(methods);
    }
    
    SKILL
    SKILL
    SKILL
    SKILL
    SKILL
    SKILL
    
    @end
    

    程序打印:

    方法名: printClassMethod:
    方法名: skill_0
    方法名: skill_1
    方法名: skill_2
    方法名: skill_3
    方法名: skill_4
    方法名: skill_5
    方法名: load
    

    __LINE__

    __LINE__表示当前行,是整数类型,示例:

    line.png

    可以在很多场景下使用__LINE__做一些事情,比如自定义Log并打印出代码的哪一行出现了问题,就可以使用这种方式:

    #ifdef DEBUG
    #define ZZLog(fmt, ...) NSLog((@"🙍♂️ ZZ log method: %s line: %d " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
    #else
    #define ZZLog(fmt, ...)
    #endif
    

    需要注意的是,这里的__LINE__所代指的行号是宏展开的地方,而不是宏定义的地方;而且宏有个特点是它实际上是一行,宏定义中使用了\只是代码显示的分隔,但实际上仍是一行,因此__LINE__仍是当前宏展开的那一行,示例:

    #import <Foundation/Foundation.h>
    #import "Test.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            [Test test];
        }
        return 0;
    }
    
    1   //
    2   //  Test.h
    3   //  TestLine
    4   //
    5   //  Created by daliu.
    6   //
    7   
    8   #import <Foundation/Foundation.h>
    9   
    10  NS_ASSUME_NONNULL_BEGIN
    11  
    12  #define PRINT_LINE_METHOD \
    13  + (void)printCurrentLine { \
    14      NSLog(@"current line is: %d", __LINE__); \
    15  }
    16  
    17  @interface Test : NSObject
    18  
    19  + (void)test;
    20  
    21  @end
    22  
    23  NS_ASSUME_NONNULL_END
    
    1   //
    2   //  Test.m
    3   //  TestLine
    4   //
    5   //  Created by daliu on 2020/12/5.
    6   //
    7   
    8   #import "Test.h"
    9   
    10  @implementation Test
    11  
    12  PRINT_LINE_METHOD
    13  // 因为宏展开所在的行是第12行,即在第12行相当于: + (void)printCurrentLine { NSLog(@"current line is: %d", __LINE__); }
    14  // 所以打印结果是 current line is: 12
    15  
    16  + (void)test {
    17      [self printCurrentLine];
    18  }
    19  
    20  @end
    

    相关文章

      网友评论

        本文标题:OC中一些预定义宏

        本文链接:https://www.haomeiwen.com/subject/ihogvrtx.html