项目中遇到的问题-2:编译第三方静态库报错、查看静态库的类型、绘制圆形

  这一周比较折腾,由于项目应用涉及到和其他产品线APP的互相通信,在高层领导英(yi)明(ta)神(hu)武(tu)的战略指导下,我开始了与其他组同事的联调之旅。这几天鄙司负责产品的上级同事莅临监工,对现在的情况又提出了一些改进,作为一名程序猿,我已经奉上我的双膝。。。

  一、集成公司其他组的.a静态库,报错:duplicate symbole for architectecture i386 XXX 

  查了一下报错的地方,都是指示.a的库和工程里面某些.m文件冲突,正好同事提到之前有碰到过这种情况,鉴于两方文件都是需要的,所以想了个办法:把其中一方的文件加了个前缀,比如CnlogsXXX.a。尝试了一下,解决了一部分问题。为什么是一部分呢,因为:

  除了集成进来的.a以外,原来的工程里面的某些.a竟然也冲突了

  

  没办法,接着查吧,最后发现用的的某个.a确实有问题,之前为了适应业务要求,兼顾旧版本的APP所以保留了二者,那这次为什么又出问题了呢,因为这次集成其他的.a,傲娇的需要加上几个编译选项到other linker flag里面去,然后就暴露了问题。

  最后请熟悉这块的同事将冲突的.a合并成了一份,删掉了多余的,这才编译通过,然后又上网查了查,基本上都是一下几种原因:

  1. 某些.h文件里面引用了.m文件(这个虽然我没遇到,不过也算是一种排查的可能原因)

  2. 某些.m文件中的变量或者方法与工程引入的.a重复;

  3. 太多了,参考这个:stackoverflow

  二、关于静态库的类型查看

  先说一下静态库一般分为模拟器版本和真机版本,各自对应不同的CPU结构;

  在模拟器上,常见的ARCH有i386(32位 mac)  X_64(64位 mac)

在真机上,常见的ARCH有3个:armv7,armv7s,arm64

armv7:对应iPhone4和iPhone4S

armv7s:对应iPhone5和iPhone5C,还有早期的iPad

arm64/armv8:对应iPhone5S和iPhone6系列,以及比较新的iPad,如iPad mini2,iPad Air

OK,需要知道一个有用的命令,lipo 用来制作静态库,查看静态库类型等。

lipo -info XXX.a  可以得到XXX.a是什么类型的库,支持哪几种CPU结构,可以看到是否是fat lib哈

(关于制作静态库,后续专门在写一下,大家可以上网搜一下,教程一堆一堆的;制作的步骤我觉得倒是其次,关键是怎么封装好一个好用的库,设计暴露出合适的接口)

三、绘制圆形

  做这个是因为我司产品觉得APP上面有的图标不够圆。。。(其实就是直接使用的截图,在大屏或者细看的情况下顶部会有切边),所以想让我们的背景圆形用代码来绘制。不得不说,我司就是这么追求极致。。。

  废话不多说,直接上代码(虽然我觉得真心没啥技术含量)

 1 #import "CustomView.h"
 2 #define radious 20.5
 3 #define PointX 24.5
 4 #define PointY 24.5
 5 
 6 @implementation CustomView
 7 
 8 -(void)drawRect:(CGRect)rect
 9 {
10     [self drawRoundRecWithPoint:CGPointMake(PointX, PointY) andRadius:radious andFillColor:_fillColor];
11 }
12 
13 //确定圆:圆心坐标X/Y  半径   颜色
14 -(void)drawRoundRecWithPoint:(CGPoint)Point andRadius:(CGFloat)radius andFillColor:(UIColor*)fillColor
15 {
16     // 1.获取上下文
17     CGContextRef context = UIGraphicsGetCurrentContext();
18     UIGraphicsPushContext(context);
19     
20     // 2.画圆
21     CGContextSetFillColorWithColor(context, fillColor.CGColor);
22     CGContextAddArc(context, Point.x, Point.y, radius, 0, 2*M_PI, 0);
23     CGContextDrawPath(context, kCGPathFill);
24     
25     UIGraphicsPopContext();
26 }
27 
28 @end

  需要注意几个点:

  1.绘制图形,步骤基本上是死的,都是先获取到上下文context对象,然后设置颜色,线的大小等,然后画图。但是在iOS7的模拟器上面,我一开始碰到了一个错误,描述的真是吓尿我了:

  <Error>: CGContextDrawPath: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

上网查原因,还是牛X的stackoverflow

I got this error in the drawInContext(..) method of my custom CALayer implementation. UIBezierPath tries to use the UIGraphicsGetCurrentContext() which is nil by default in a custom layer. The online documentation explains this very clearly -

If you are not using a UIView object to do your drawing, however, you must push a valid context onto the stack manually using the UIGraphicsPushContext function.
Here's the code that finally worked with my comments inline (Swift code, but the solution is the same regardless)

override func drawInContext(ctx: CGContext!) {  
    var path = UIBezierPath()

    // 1. Make sure you push the CGContext that was first passed into you.
    UIGraphicsPushContext(ctx)
    path.moveToPoint(CGPoint(x: 0, y: 0))
    path.addLineToPoint(CGPoint(x: 150, y: 150))
    var lineColor = UIColor.blueColor()
    lineColor.setStroke()
    path.lineWidth = 2
    path.stroke(
    // 2. Pop the context after you are done.
    UIGraphicsPopContext()

  2.实现的过程中,忽然想起来前几天在微博上看到VVeibo的实现分析,有一个图标也是看上去是圆形,但其实是方形图片加了一层圆形的遮罩。我也可以试试,于是在原来图片上加了个遮罩,但是。。。效果不甚理想啊,圆形似乎不是很圆。。很圆。。。

  3.为了做到更好的通用和扩展,我定义了圆的填充颜色,半径和圆点的point都用宏定义,然后再drawRect方法里面调用,只需要传给被调方法具体的属性,就可以返回一个绘制好的填充圆。时刻牢记MJ大神教导:

  定义接口,是要让别人用的爽。

 

  好的,今天就到这里。

 

 

 

  

posted @ 2015-05-29 21:29  wdwblue  阅读(387)  评论(0编辑  收藏  举报