宏定义

5.0.0版本需求对小铅笔进行了整体页面修改,我调整了页面的布局,并实现了一套适配iPad的方案,方案就是把图片,文字,间距,圆角等都按设计稿的比例进行了放大。
效果还不错(大佬说这效果就像老人机:D),就是方法比较笨,需要在每个约束的地方和字体大小的设置给一个转换后的值。

_coverBgView.layer.cornerRadius = SPACE(4);
_nameLabel.font = TP_GLOBAL_FONT_SIZE(SPACE(14));
[self.cornerRadiusView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self);
        make.leading.mas_equalTo(self).mas_offset(SPACE(10));
        make.trailing.mas_equalTo(self).mas_offset(SPACE(-10));
        make.height.mas_equalTo(SPACE(20));
    }];

这里的值转换我用了宏来写,第一版是这样

#define SPACE(i) (i*[UIScreen mainScreen].bounds.size.width*1.0/375)

后来觉得在手机上不需要按照比例调整,只在iPad上启动这种模式就好了,改成了这样

#define SPACE(i) (IS_IPAD ? i*[UIScreen mainScreen].bounds.size.width*1.0/375 : i)

然后问题就来了,作品栏跟角色栏的高度相差的就是红色框框的35pt的tab控件,但是效果是作品栏矮了很多。
在这里插入图片描述
乍看代码好像也没问题

self.roleCellSize = CGSizeMake(screenWidth, roleCellHeight + SPACE(45));
self.productCellSize = CGSizeMake(screenWidth, roleCellHeight + SPACE(45+35));

把值打印后发现,SPACE(45)值为122.88,SPACE(45+35)值为140.573,80*1024/375=218.453才是正确的答案,为什么在宏里就算不对?

宏(Macro),是一种批量处理的称谓。计算机科学里的宏是一种抽象(Abstraction),它根据一系列预定义的规则替换一定的文本模式。

百度一下宏定义得知,它是一种替换。

#define SPACE(i) (IS_IPAD ? i*[UIScreen mainScreen].bounds.size.width*1.0/375 : i)

SPACE(45+35),就是等于45+3510241.0/375,所以根据加减乘除的优先级运算,并没有得出理想中的结果。然后我就把能加上括号的地方都加上了括号,

#define SPACE(i) (IS_IPAD ? ((i)*[UIScreen mainScreen].bounds.size.width*1.0/375) : i)

这样子,无论是SPACE(45+35)还是SPACE(45+35)*35,结果都是正确的。

下面学习一下系统的取两数中较小值的宏MIN(A,B)

#define __NSX_PASTE__(A,B) A##B

#if !defined(MIN)
    #define __NSMIN_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L); })
    #define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__)
#endif

逐步来看一下这个宏,先解释三个比较陌生的地方。
1、 __COUNTER__是一个计数器,从0开始计数,每次调用加1,这里就是当做是一个通常配合##使用,用于构建唯一的标识符。

#define __NSX_PASTE__(A,B) A##B

这里的这个宏利用外部传入的参数与__COUNTER__连接,生成一个唯一的标识。
2、##是一个连接符,它的效果如下

#define AA(a, b) a##b
NSLog(@"%@", [AA(NS, String) stringWithFormat:@"aa"]);
NSLog(@"%d", AA(10, 0));

打印结果为
在这里插入图片描述
3、这一段看起来像是对传入的参数A进行了一个处理,

__typeof__(A) __NSX_PASTE__(__a,L) = (A);

刚才有说__NSX_PASTE__(__a,L),就是形成了一个唯一标识,我们把这个标识当成是x。

__typeof__(A) x = (A);

typeof在这里的意思是把x定义成A指向的数据类型,这样就声明一个同样数据类型的参数x来保存A的原始值,这样做是为了保证2和1++比较的正确性。
感受一下typeof的效果,声明两个宏一个有typeof,一个没有,

#define MINI(A,B) (A < B ? A : B)
#define MINII(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
int a = 1; int b = 1;
NSLog(@"%d   %d", MINI(2, a++), MINII(2, b++));

调用,打印结果
在这里插入图片描述
如果取2跟1++的最小值,正确结果应该是1。因为前者因为1++在三目运算里又自加了一次,导致答案错了,如果这发生在更加复杂的运算,就更影响运算的结果了。
4、
在这里插入图片描述
最后我们就可以很轻松得解读这个宏,利用了计数器连接,生成了两个唯一标识的参数,参数的值为传参的原始值,再用两个参数来比较得出了最小值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值