IOS 宏定义

来源:互联网 发布:旺旺号是不是淘宝昵称 编辑:程序博客网 时间:2024/06/06 13:08


喵神宏定义的黑魔法学到了很多,在这里总结下。

一、单个“#”的使用

单个“#”表示将后面紧接的参数变成 C 字符串,如 :

#define Name(pro) @#pro

- (void)testName {

   NSLog(@"|%@|",Name(self.dataArray));

}

2015-10-20 11:34:45.691 Shadow[1878:71990] setUp

2015-10-20 11:34:45.692 Shadow[1878:71990] |self.dataArray|

2015-10-20 11:34:45.692 Shadow[1878:71990] tearDown




二、双“##”的使用
双“##”表示连接运算符,是将前后两个参数名连接起来组成新的参数名。
听起来有点不可思议,看个例子吧。

#define __CZ_AppendName(a,b) a##b


- (void)testAppendMacros {

   int a =1 , b  =2, ab =0 ;

   int oldab = ab;

    __CZ_AppendName(a,b) =3;

    NSLog(@"a = %d , b = %d , oldab = %d , ab = %d ",a,b,oldab,ab);

}

2015-10-20 11:48:05.109 Shadow[1952:78380] setUp

2015-10-20 11:48:05.109 Shadow[1952:78380] a = 1 , b = 2 , oldab = 0 , ab = 3 

2015-10-20 11:48:05.109 Shadow[1952:78380] tearDown




三、宏定义换行 “\

有时候宏定义太长,需要换行显示使得排版精美。


#define MASAttachKeys(...)                                                    \

    NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__);     \

    for (id key in keyPairs.allKeys) {                                        \

        id obj = keyPairs[key];                                               \

        NSAssert([obj respondsToSelector:@selector(setMas_key:)],             \

                 @"Cannot attach mas_key to %@", obj);                        \

        [obj setMas_key:key];                                                 \

    }




四、可变参数宏 __VA_ARGS__

OC在定义使用可变参数宏是,用...例如:

#define __CZ_ParamterNames(...) (@"" # __VA_ARGS__)


- (void)testMestor {

   float a ,b, view1,view2;

    //获取所有的key

   NSLog(@"Name = %@",__CZ_ParamterNames(a,b,view1,view2));

}


2015-10-20 11:50:27.576 Shadow[1974:80161] setUp

2015-10-20 11:50:27.576 Shadow[1974:80161] Name = a,b,view1,view2

2015-10-20 11:50:27.585 Shadow[1974:80161] tearDown


现在开始动手实践吧


学了这么多新知识,就要动手练习练习,手写约束的同行都是知道iOS的NSDictionaryOfVariableBindings(...)

宏定义挺神奇的,传入View,即可得到包含同名元素的字典。 不妨模仿下这个宏:

先来简单分析下:

1.最明显的是接受可变参数

2.要把这些变量名字符串化得到keys

3.需要寻找NSDictionary对应的接受可变参数宏的方法

解决:

1.先来解决第一步,先定义宏__CZ_DictionaryWithValue(...)

2.将参数字符串化 @#__VA_ARGS__  

    3.需要相关方法,

+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;

+ (instancetype)arrayWithObjects:(id)firstObj, ...NS_REQUIRES_NIL_TERMINATION;

接下来就是简单地将一个字符串转化成一个keys数组:  componentsSeparatedByString


整理: 

#define __CZ_DictionaryWithValue(...) ({                                                                   \

                                            NSDictionary* dic = [NSDictionary dictionaryWithObjects:       \

                                                                [NSArray arrayWithObjects:__VA_ARGS__,nil] \

                                                                forKeys:                                   \

                                                                [@#__VA_ARGS__                                                          componentsSeparatedByString:@","]];              \

                                            dic;                                                           \

                                                        })



- (void)testMestor {  

   NSString* str =@"haha";

   NSNumber* num =@1;

    NSDictionary* dic =__CZ_DictionaryWithValue(str,num);

    

   NSLog(@"dic = %@",dic);


}

2015-10-20 11:50:27.576 Shadow[1974:80161] setUp

2015-10-20 11:50:27.577 Shadow[1974:80161] dic = {

    num = 1;

    str = haha;

}

2015-10-20 11:50:27.585 Shadow[1974:80161] tearDown



1 0