天天看點

Masonry源碼解析(二)

四、一個小技巧

   Masonry中的一個函數值得我們學習,其作用是對任何類型的值進行一層對象包裝,函數如下:

//值包裝宏

#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))

static inline id _MASBoxValue(const char *type, ...) {

   va_list v;

   va_start(v, type);

   id obj = nil;

   //進行類型判斷 結構體包裝成NSValue 基本類型包裝成NSNumber

   if (strcmp(type, @encode(id)) == 0) {

       id actual = va_arg(v, id);

       obj = actual;

   } else if (strcmp(type, @encode(CGPoint)) == 0) {

       CGPoint actual = (CGPoint)va_arg(v, CGPoint);

       obj = [NSValue value:&actual withObjCType:type];

   } else if (strcmp(type, @encode(CGSize)) == 0) {

       CGSize actual = (CGSize)va_arg(v, CGSize);

   } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {

       MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);

   } else if (strcmp(type, @encode(double)) == 0) {

       double actual = (double)va_arg(v, double);

       obj = [NSNumber numberWithDouble:actual];

   } else if (strcmp(type, @encode(float)) == 0) {

       float actual = (float)va_arg(v, double);

       obj = [NSNumber numberWithFloat:actual];

   } else if (strcmp(type, @encode(int)) == 0) {

       int actual = (int)va_arg(v, int);

       obj = [NSNumber numberWithInt:actual];

   } else if (strcmp(type, @encode(long)) == 0) {

       long actual = (long)va_arg(v, long);

       obj = [NSNumber numberWithLong:actual];

   } else if (strcmp(type, @encode(long long)) == 0) {

       long long actual = (long long)va_arg(v, long long);

       obj = [NSNumber numberWithLongLong:actual];

   } else if (strcmp(type, @encode(short)) == 0) {

       short actual = (short)va_arg(v, int);

       obj = [NSNumber numberWithShort:actual];

   } else if (strcmp(type, @encode(char)) == 0) {

       char actual = (char)va_arg(v, int);

       obj = [NSNumber numberWithChar:actual];

   } else if (strcmp(type, @encode(bool)) == 0) {

       bool actual = (bool)va_arg(v, int);

       obj = [NSNumber numberWithBool:actual];

   } else if (strcmp(type, @encode(unsigned char)) == 0) {

       unsigned char actual = (unsigned char)va_arg(v, unsigned int);

       obj = [NSNumber numberWithUnsignedChar:actual];

   } else if (strcmp(type, @encode(unsigned int)) == 0) {

       unsigned int actual = (unsigned int)va_arg(v, unsigned int);

       obj = [NSNumber numberWithUnsignedInt:actual];

   } else if (strcmp(type, @encode(unsigned long)) == 0) {

       unsigned long actual = (unsigned long)va_arg(v, unsigned long);

       obj = [NSNumber numberWithUnsignedLong:actual];

   } else if (strcmp(type, @encode(unsigned long long)) == 0) {

       unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);

       obj = [NSNumber numberWithUnsignedLongLong:actual];

   } else if (strcmp(type, @encode(unsigned short)) == 0) {

       unsigned short actual = (unsigned short)va_arg(v, unsigned int);

       obj = [NSNumber numberWithUnsignedShort:actual];

   }

   va_end(v);

   return obj;

}

其中@encode()是一個編譯時特性,其可以将傳入的類型轉換為标準的OC類型字元串。

繼續閱讀