来自MixPanel的Log写法

作者: iLees | 来源:发表于2016-08-10 12:33 被阅读99次

    <h6>首先看一下代码:</h6>

    static inline void MPLog(NSString *format, ...) {
        __block va_list arg_list;
        va_start (arg_list, format);
        NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list];
        va_end(arg_list);
        NSLog(@"[Mixpanel] %@", formattedString);
    }
    
    #ifdef MIXPANEL_DEBUG
    #define MixpanelDebug(...) MPLog(__VA_ARGS__)
    #else
    #define MixpanelDebug(...)
    #endif
    

    <h6>重点关注的是MPLog的实现,我们可以分以下两点解剖该函数:</h6>
    1、static inline
    inline函数有点类似于宏,内联函数代码会被直接嵌入到被调用的地方,调用几次就会嵌入几次。这样省去了函数调用时的一些额外开销,例如保存和恢复函数返回地址等等。这样加快了速度,但调用次数多的话,会导致可执行文件变大。为了避免这一弱点,内联函数一般都会和static一起出现,从而避免被其它编译单元调用。

    2、va_start、va_start
    在C语言中,我们经常会见到这样的传参方式:

    void func(part_list, ...);
    

    函数参数是以栈的形式存取的,从右至左入栈。参数存放在内存的堆栈段中,在执行函数的时候,从最后一个开始入栈,这样栈底是高地址栈顶是低地址。例如:void func(int x, float y, char z);函数调用的时候,进栈顺序是z->y->x,内存中变量存放次序是x->y->z。因此,我们只要知道一个变量的地址和其他变量的类型,通过指针移位运算就可以顺藤摸瓜找到其它的参数,例如:

    
    void fun(int a, ...) 
    { 
      int *temp = &a;
      temp++;
      for (int i = 0; i < a; ++i) 
      { 
        cout << *temp << endl; 
        temp++; 
      } 
    }
    int main() 
    { 
      int a = 1; 
      int b = 2; 
      int c = 3; 
      int d = 4; 
      fun(4, a, b, c, d); 
      system("pause"); 
      return 0; 
    } 
    
    Output:: 
    1 
    2 
    3 
    4
    

    对于获取省略号指定的参数,在函数体中声明一个va_list,然后用va_start函数来获取参数列表中的参数,使用完毕后调用va_end来结束,例如:

    /*函数原型声明,至少需要一个确定的参数,注意括号内的省略号*/ 
    int demo( char, ... ); 
    void main( void ) 
    { 
       demo("DEMO", "This", "is", "a", "demo!", ""); 
    } 
    
    /*括号内的省略号表示可选参数*/ 
    int demo( char msg, ... ) 
    { 
           /*定义保存函数参数的结构*/
       va_list argp; 
       int argno = 0; 
       char para; 
         /*argp指向传入的第一个可选参数,msg是最后一个确定的参数*/ 
       va_start( argp, msg ); 
       while (1) 
           { 
            para = va_arg( argp, char); 
               if ( strcmp( para, "") == 0 ) 
                   break; 
               printf("Parameter #%d is: %s\n", argno, para); 
               argno++; 
    } 
    va_end( argp ); 
    /*将argp置为NULL*/
    return 0; 
    }
    

    相关文章

      网友评论

        本文标题:来自MixPanel的Log写法

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