彼针实对第1接触,我边立虽然梳理了诸多类的事件,但是还有为数不少从来不于统计上,比如摇摇一摇触发之轩然大波,计步器触发的事件,tabBar点击触发之波相当,还格外有差不多己恐怕无到想的事件,我现发如果依照作者的意向,按照事件触发的色去一个一个的展开hook操作的话,工作片雅大,而且要会发生遗漏的。尤是该涉及到发方些法苹果没有放为开发者,我们开展处理的话语比较辛苦。开员发人估计被算要累啊。
针对第2碰,按作照者的来意,会现发点击后里面还有层层的判断,如何绕了层层的判定也?这个我会以连下详细阐述。
针对第4沾,我以上头都实现了了。
针对第5触及,在具体的状况遇真正存在者不同的页面中,甚至同一之页面被不同的按钮对诺在同一个轩然大波如此的问题。如果以参考博客作者的思绪确实处理起来非常是麻烦。
返璞归真
  针对地方出现的泥坑,我当惦记生没起重新好之艺术去解决为。首先想到我们统计用户操的发事件,并是免为统计用户点击了某按钮,或者进行了有手势操作,调了用有代理方。而为是了统计用户进行这个操作的目的是啊,是为购物,还是为分享当。所以我就是打破参考博客作者的思绪,不再对按钮,手势,单元格选中等事件开展hook,而是指向用户之目的事件触发的方式进行hook,事件就是是事件,没有自的分。也尽管是hook就提示的事件,中间层层的逻辑判断,我非欲考虑,我偏偏考虑hook的目的事件。举例个子,用户一旦走分享-
(void)goShare;
,我非体贴用是户否点击了按钮,或者tap手势触发了艺术,或者单元格被蒙摘,我仅关注分享的方法-
(void)goShare;

3.4.2 文件名函数

获得目录函数: $(dir <names…>)

功效: 从文本称行 <names> 中取出目录部分

归来: 文件称行 <names> 中的目录部分

# Makefile 内容
all:
    @echo $(dir /home/a.c ./bb.c ../c.c d.c)


# bash 中执行 make
$ make
/home/ ./ ../ ./

 

抱文件函数: $(notdir <names…>)

作用: 从文本称行 <names> 中取出非目录部分

归来: 文件称行 <names> 中之非目录部分

# Makefile 内容
all:
    @echo $(notdir /home/a.c ./bb.c ../c.c d.c)

# bash 中执行 make
$ make
a.c bb.c c.c d.c

 

取后缀函数: $(suffix <names…>)

成效: 从文本称行 <names> 中取出各个文件称的后缀

回来: 文件称行 <names> 中逐条文件称的后缀,
没有后缀则归空字符串

# Makefile 内容
all:
    @echo $(suffix /home/a.c ./b.o ../c.a d)

# bash 中执行 make
$ make
.c .o .a

 

取前缀函数: $(basename <names…>)

力量: 从文本称行 <names> 中取出各个文件称之前缀

回去: 文件称行 <names> 中相继文件称之前缀,
没有前缀则归空字符串

# Makefile 内容
all:
    @echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)


# bash 中执行 make
$ make
/home/a ./b ../c /home/

 

加后缀函数: $(addsuffix <suffix>,<names…>)

功效: 把后缀 <suffix> 加到 <names> 中之每个单词后面

回到: 加然后缀的文书称行

# Makefile 内容
all:
    @echo $(addsuffix .c,/home/a b ./c.o ../d.c)


# bash 中执行 make
$ make
/home/a.c b.c ./c.o.c ../d.c.c

 

加前缀函数: $(addprefix <prefix>,<names…>)

作用: 把前面缀 <prefix> 加到 <names> 中的每个单词前面

回到: 加过前缀的文件称行

# Makefile 内容
all:
    @echo $(addprefix test_,/home/a.c b.c ./d.c)

# bash 中执行 make
$ make
test_/home/a.c test_b.c test_./d.c

 

连日函数: $(join <list1>,<list2>)

效益: <list2> 中对应的光词加至 <list1> 后面

归来: 连接后底字符串

# Makefile 内容
all:
    @echo $(join a b c d,1 2 3 4)
    @echo $(join a b c d,1 2 3 4 5)
    @echo $(join a b c d e,1 2 3 4)

# bash 中执行 make
$ make
a1 b2 c3 d4
a1 b2 c3 d4 5
a1 b2 c3 d4 e

 

+ (void)configureDelegateEvent{
 [JKBViewController aspect_hookSelector:@selector(tableView:didSelectRowAtIndexPath:) 
                            withOptions:AspectPositionAfter 
                             usingBlock:^(id<AspectInfo> data){ 
                                 [self JKHandleEvent:data];
                             } error:nil
  ];
}

2.4 伪目标

私目标并无是一个”目标(target)”, 不像真的靶子那样会变动一个靶文件.

卓越的非官方目标是 Makefile 中因故来清理编译过程被中文件之 clean 伪目标,
一般格式如下:

.PHONY: clean   <-- 这句没有也行, 但是最好加上
clean:
    -rm -f *.o

 

造一慢慢悠悠适合好公司求的用户作为统计体系,相信是成千上万营业人员的只求,也是开发人员对技术的的尽着追求。下面我啊大家分一享下自己吗公司制作的用户作为统计体系。用户作为统计(User
Behavior Statistics,
UBS)一直是移动互联网产品受到必要的环节,也俗称埋点。对于产品经理,运营人员的话,埋点当然是进一步多,覆盖范围越宽广越好。废话废话就无小了,这里自己重点使用了AOP面向切片编程的思想来缓解者问题之。
参照博客:参考博客地址。首先声明,我这边并没有了照搬别人博客,这里主要是挨别人博客思路去倒,走上前死胡同,然后返璞归真,用自己之思路去贯彻的。之所以将人家的笔触写下去讨论,就是为着证实思考的长河有时也老重要。

3.1 嵌套Makefile

当 Makefile 初级语法中一度涉嫌了引用其它 Makefile的方法.
这里发生其它一样种写法, 并且可以往引用的外 Makefile 传递参数.

以身作则: (不传递参数, 只是调用子文件夹 other 中的Makefile)

# Makefile 内容
all:
    @echo "主 Makefile begin"
    @cd ./other && make
    @echo "主 Makefile end"


# ./other/Makefile 内容
other-all:
    @echo "other makefile begin"
    @echo "other makefile end"

# bash中执行 make
$ ll
total 28K
-rw-r--r-- 1 wangyubin wangyubin  104 Sep 23 20:43 Makefile
-rw-r--r-- 1 wangyubin wangyubin  17K Sep 23 20:44 makefile.org   <-- 这个文件不用管
drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 23 20:42 other
$ ll other/
total 4.0K
-rw-r--r-- 1 wangyubin wangyubin 71 Sep 23 16:11 Makefile

$ make
主 Makefile begin
make[1]: Entering directory `/path/to/test/makefile/other'
other makefile begin
other makefile end
make[1]: Leaving directory `/path/to/test/makefile/other'
主 Makefile end

 

以身作则: (用export传递参数)

# Makefile 内容
export VALUE1 := export.c    <-- 用了 export, 此变量能够传递到 ./other/Makefile 中
VALUE2 := no-export.c        <-- 此变量不能传递到 ./other/Makefile 中

all:
    @echo "主 Makefile begin"
    @cd ./other && make
    @echo "主 Makefile end"


# ./other/Makefile 内容
other-all:
    @echo "other makefile begin"
    @echo "VALUE1: " $(VALUE1)
    @echo "VALUE2: " $(VALUE2)
    @echo "other makefile end"

# bash中执行 make
$ make
主 Makefile begin
make[1]: Entering directory `/path/to/test/makefile/other'
other makefile begin
VALUE1:  export.c        <-- VALUE1 传递成功
VALUE2:                  <-- VALUE2 传递失败
other makefile end
make[1]: Leaving directory `/path/to/test/makefile/other'
主 Makefile end

 

*补充* export 语法格式如下:

  • export variable = value
  • export variable := value
  • export variable += value

 

+ (void)JKhandlePV:(id<AspectInfo>)data status:(JKUBSPVSTATUS)status;
+ (void)JKHandleEvent:(id<AspectInfo>)data EventID:(NSInteger)eventId;

3.4.1 字符串函数

字符串替换函数: $(subst <from>,<to>,<text>)

成效: 把字符串<text> 中之 <from> 替换为 <to>

回到: 替换了之字符串

# Makefile 内容
all:
    @echo $(subst t,e,maktfilt)  <-- 将t替换为e

# bash 中执行 make
$ make
makefile

 

模式字符串替换函数: $(patsubst
<pattern>,<replacement>,<text>)

力量: 查找<text>中之单词(单词以”空格”, “tab”, “换行”来分)
是否符合 <pattern>, 符合的话, 用 <replacement> 替代.

回: 替换了的字符串

# Makefile 内容
all:
    @echo $(patsubst %.c,%.o,programA.c programB.c)

# bash 中执行 make
$ make
programA.o programB.o

 

去空格函数: $(strip <string>)

功效: 去丢 <string> 字符串中初步和末段的空字符

返: 被失去丢空格的字符串值

# Makefile 内容
VAL := "       aa  bb  cc "

all:
    @echo "去除空格前: " $(VAL)
    @echo "去除空格后: " $(strip $(VAL))

# bash 中执行 make
$ make
去除空格前:         aa  bb  cc 
去除空格后:   aa bb cc

 

摸索字符串函数: $(findstring <find>,<in>)

作用: 在字符串 <in> 中检索 <find> 字符串

返: 如果找到, 返回 <find> 字符串,  否则回空字符串

# Makefile 内容
VAL := "       aa  bb  cc "

all:
    @echo $(findstring aa,$(VAL))
    @echo $(findstring ab,$(VAL))

# bash 中执行 make
$ make
aa

 

过滤函数: $(filter <pattern…>,<text>)

效益: 以 <pattern> 模式过滤字符串 <text>, *保留* 符合模式
<pattern> 的单词, 可以生多独模式

返回: 符合模式 <pattern> 的字符串

# Makefile 内容
all:
    @echo $(filter %.o %.a,program.c program.o program.a)


# bash 中执行 make
$ make
program.o program.a

 

反过滤函数: $(filter-out <pattern…>,<text>)

效果: 以 <pattern> 模式过滤字符串 <text>, *去除* 符合模式
<pattern> 的单词, 可以有多单模式

回去: 不符合模式 <pattern> 的字符串

# Makefile 内容
all:
    @echo $(filter-out %.o %.a,program.c program.o program.a)

# bash 中执行 make
$ make
program.c

 

排序函数: $(sort <list>)

力量: 给字符串 <list> 中的单纯词排序 (升序)

回去: 排序后的字符串

# Makefile 内容
all:
    @echo $(sort bac abc acb cab)

# bash 中执行 make
$ make
abc acb bac cab

 

取单词函数: $(word <n>,<text>)

功能: 取字符串 <text> 中之 第<n>个单词 (n从1开始)

返: <text> 中之第<n>个单词, 如果<n> 比 <text>
中单单词个数要特别, 则返回空字符串

# Makefile 内容
all:
    @echo $(word 1,aa bb cc dd)
    @echo $(word 5,aa bb cc dd)
    @echo $(word 4,aa bb cc dd)

# bash 中执行 make
$ make
aa

dd

 

取单词串函数: $(wordlist <s>,<e>,<text>)

功效: 从字符串<text>中取从<s>开始到<e>的独词串.
<s>和<e>是一个数字.

回: 从<s>到<e>的字符串

# Makefile 内容
all:
    @echo $(wordlist 1,3,aa bb cc dd)
    @echo $(word 5,6,aa bb cc dd)
    @echo $(word 2,5,aa bb cc dd)


# bash 中执行 make
$ make
aa bb cc

bb

 

仅词个数统计函数: $(words <text>)

效能: 统计字符串 <text> 中唯有词之个数

回: 单词个数

# Makefile 内容

all:
    @echo $(words aa bb cc dd)
    @echo $(words aabbccdd)
    @echo $(words )

# bash 中执行 make
$ make
4
1
0

 

首单独词函数: $(firstword <text>)

意义: 取字符串 <text> 中之首先单单词

回: 字符串 <text> 中的首先独单词

# Makefile 内容
all:
    @echo $(firstword aa bb cc dd)
    @echo $(firstword aabbccdd)
    @echo $(firstword )

# bash 中执行 make
$ make
aa
aabbccdd

 

这边描绘图片描述

3.4.5 call – 创建新的参数化函数

语法:

$(call <expression>,<parm1>,<parm2>,<parm3>…)

 

示例:

# Makefile 内容
log = "====debug====" $(1) "====end===="

all:
    @echo $(call log,"正在 Make")

# bash 中执行 make
$ make
====debug==== 正在 Make ====end====

 

事件统计:Event
  事件统计要是当用户触发事件频仍展开记录保留,然后在恰当的时节用记之录数据发送给后台服务器进行拍卖。按照文章开始参考博客所说,简单以起事分成了UIButotn,UIControl,UIGestureRecognizer以及点击UITableView单元格cell触发的波,点击UICollectionView单元格cell触发的轩然大波。
  按照此思路我首先对UIButton,UIControl触发的波开展拍卖:

2.2.2 变量替换

# Makefile内容
SRCS := programA.c programB.c programC.c
OBJS := $(SRCS:%.c=%.o)

all:
    @echo "SRCS: " $(SRCS)
    @echo "OBJS: " $(OBJS)

# bash中运行make
$ make
SRCS:  programA.c programB.c programC.c
OBJS:  programA.o programB.o programC.o

 

发无发生受调用,被调用的时段我是否可进记行录操作。另外唯一确定一个措施,除了selector,还要起连带的target(方法的贯彻者,或者信息接受者)。针上面第5触及,不同按钮对应同一个事件,一般情形下事件相同target不同,我们是力所能及区分之出的。当了解也存和一个页面及之异按钮触发的和一个事件,这种状况下非是极常见,函数外面包一层,改个别的讳分别一下就哼了,不过EnvetID还是如一如既往的。
  为了重新好之有益大家,我当时边按自照己的思绪写了一个pod库,下面先说一下温馨的plist文件文件:

2.8 指定 Makefile, 指定特定对象

默认执行 make 命令时, GNU make在当前目录下依次找下面3个公文
“GNUmakefile”, “makefile”, “Makefile”,

找到呼应文件后, 就起推行此文件被的首先单对象(target).
如果找不顶就3独公文就报错.

 

非默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的 目标.

示例:

# Makefile文件名改为 MyMake, 内容
target1:
    @echo "target [1]  begin"
    @echo "target [1]  end"

target2:
    @echo "target [2]  begin"
    @echo "target [2]  end"

# bash 中执行 make
$ ls
Makefile
$ mv Makefile MyMake
$ ls
MyMake
$ make                     <-- 找不到默认的 Makefile
make: *** No targets specified and no makefile found.  Stop.
$ make -f MyMake           <-- 指定特定的Makefile
target [1]  begin
target [1]  end
$ make -f MyMake target2   <-- 指定特定的目标(target)
target [2]  begin
target [2]  end

 

pod "JKUBS"

2.9 make 参数介绍

make 的参数有不少, 可以经 make -h 去查看,
下面就介绍几个自觉着于可行的.

参数

含义

–debug[=<options>] 输出make的调试信息, options 可以是 a, b, v
-j –jobs 同时运行的命令的个数, 也就是多线程执行 Makefile
-r –no-builtin-rules 禁止使用任何隐含规则
-R –no-builtin-variabes 禁止使用任何作用于变量上的隐含规则
-B –always-make 假设所有目标都有更新, 即强制重编译

 

[UIViewController aspect_hookSelector:@selector(viewDidAppear:) withOptions:AspectPositionAfter usingBlock:^(id data){
            [self JKhandlePV:data status:JKUBSPV_ENTER];
        } error:nil];

        [UIViewController aspect_hookSelector:@selector(viewDidDisappear:) withOptions:AspectPositionAfter usingBlock:^(id data){
            [self JKhandlePV:data status:JKUBSPV_LEAVE];
        } error:nil];

2.2.3 变量追加值 +=

# Makefile内容
SRCS := programA.c programB.c programC.c
SRCS += programD.c

all:
    @echo "SRCS: " $(SRCS)

# bash中运行make
$ make
SRCS:  programA.c programB.c programC.c programD.c

 

经此实现我们能够好对点击UITableView单元格cell触发的事件进行统计,但是本着参博考客作者的笔触就同步一步做下来,做到这里我心坎有种不的妙感觉。
举手投足上前死胡同
以下是参照的博客作者以付出之进程遭到相遇的题材

2.2.5 目标变量

打算是若变量的作用域仅限于此目标(target), 而非像前例子中定义之变量,
对整Makefile都出效.

语法:

  • <target …> :: <variable-assignment>
  • <target …> :: override <variable-assignment>
    (override作用参见 变量覆盖的牵线)

 

示例:

# Makefile 内容
SRCS := programA.c programB.c programC.c

target1: TARGET1-SRCS := programD.c
target1:
    @echo "SRCS: " $(SRCS)
    @echo "SRCS: " $(TARGET1-SRCS)

target2:
    @echo "SRCS: " $(SRCS)
    @echo "SRCS: " $(TARGET1-SRCS)

# bash中执行make
$ make target1
SRCS:  programA.c programB.c programC.c
SRCS:  programD.c

$ make target2     <-- target2中显示不了 $(TARGET1-SRCS)
SRCS:  programA.c programB.c programC.c
SRCS:

 

里面起些许只章程而重点说一下。

2.1.1 规则语法

平整主要有2局部: 依赖关系 和 生成靶子的方法.

语法有以下2种植:

target ... : prerequisites ...
    command
    ...

或者

target ... : prerequisites ; command
    command
    ...

*注* command太长, 可以用 “\”
作为换行符

 

+ (void)configPV{
    for (NSString *vcName in [JKUBS shareInstance].configureData[JKUBSPVKey]) {

        Class target = NSClassFromString(vcName);
        [target aspect_hookSelector:@selector(viewDidAppear:) withOptions:AspectPositionAfter usingBlock:^(id data){
            [self JKhandlePV:data status:JKUBSPV_ENTER];
        } error:nil];

        [target aspect_hookSelector:@selector(viewDidDisappear:) withOptions:AspectPositionAfter usingBlock:^(id data){
            [self JKhandlePV:data status:JKUBSPV_LEAVE];
        } error:nil];
    }


}

2.10 Makefile 隐含规则

此间才排一个以及编译C相关的.

编译C时,<n>.o 的目标会自行推导为 <n>.c

# Makefile 中
main : main.o
    gcc -o main main.o

#会自动变为:
main : main.o
    gcc -o main main.o

main.o: main.c    <-- main.o 这个目标是隐含生成的
    gcc -c main.c

 

+ (void)configGestureRecognizerEvent{ 
Class UIGestureRecognizerTarget =NSClassFromString(@"UIGestureRecognizerTarget"); 
[UIGestureRecognizerTarget aspect_hookSelector:@selector(_sendActionWithGestureRecognizer:) 
                                   withOptions:AspectPositionAfter 
                                    usingBlock:^(id<AspectInfo> data){ 
                                        [self JKHandleEvent:data];
                                    } error:nil
];
}

3.5 Makefile中部分GNU约定俗成的不法目标

一旦生了当Linux上, 从源码安装软件的涉的讲话, 就见面针对 make clean, make
install 比较成熟悉.

譬如说 clean, install 这些私自目标, 广为人知, 不用解释就是大家理解是啊意思了.

下面列举部分常用之野鸡目标,
如果在融洽种的Makefile合理采取这些伪目标吧,
可以给咱团结一心之Makefile看起再规范, 呵呵 🙂

伪目标

含义

all 所有目标的目标,其功能一般是编译所有的目标
clean 删除所有被make创建的文件
install 安装已编译好的程序,其实就是把目标可执行文件拷贝到指定的目录中去
print 列出改变过的源文件
tar 把源程序打包备份. 也就是一个tar文件
dist 创建一个压缩文件, 一般是把tar文件压成Z文件. 或是gz文件
TAGS 更新所有的目标, 以备完整地重编译使用
check 或 test 一般用来测试makefile的流程

眼看简单独方式都要以JKUBS的category进行重载,来举行实际的兑现。
像页面活动的记录,事件的记录。
制作用户作为统计体系,我顿时边都成功了AOP思想下之轩然大波采访,具体什么记录,保存,发给送后台,这里就是非详细说明了。
代码下载地址
使用pod如下:

2.2.4 变量覆盖 override

图是使 Makefile中定义之变量能够覆盖 make 命令参数中指定的变量

语法:

  • override <variable> = <value>
  • override <variable> := <value>
  • override <variable> += <value>

 

下通过一个例证体会 override 的图:

# Makefile内容 (没有用override)
SRCS := programA.c programB.c programC.c

all:
    @echo "SRCS: " $(SRCS)

# bash中运行make
$ make SRCS=nothing
SRCS:  nothing

#################################################

# Makefile内容 (用override)
override SRCS := programA.c programB.c programC.c

all:
    @echo "SRCS: " $(SRCS)

# bash中运行make
$ make SRCS=nothing
SRCS:  programA.c programB.c programC.c

 

#import "JKUBS.h"

NSString const *JKUBSPVKey = @"PV";
NSString const *JKUBSEventKey = @"Event";
NSString const *JKUBSEventIDKey = @"EventID";
NSString const *JKUBSEventConfigKey = @"EventConfig";
NSString const *JKUBSSelectorStrKey = @"selectorStr";
NSString const *JKUBSTargetKey = @"target";

@interface JKUBS()

@property (nonatomic,strong,readwrite) NSDictionary *configureData;

@end

@implementation JKUBSstatic JKUBS *_ubs =nil;
+ (instancetype)shareInstance{ 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{
         _ubs = [JKUBS new]; 
    }); 

    return _ubs;
}

+ (void)configureDataWithJSONFile:(NSString *)jsonFilePath{ 
    NSData *data = [NSData dataWithContentsOfFile:jsonFilePath]; 
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data 
                                                        options:NSJSONReadingMutableLeaves 
                                                          error:nil ]; 
    [JKUBS shareInstance].configureData = dic; 
    if ([JKUBS shareInstance].configureData) { 
        [self setUp]; 
    }

}

+ (void)configureDataWithPlistFile:(NSString *)plistFileName{ 
    NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:plistFileName ofType:@"plist"]]; 
    [JKUBS shareInstance].configureData = dic; 
    if ([JKUBS shareInstance].configureData) {
         [self setUp]; 
    }
}

+ (void)setUp{ 
    [self configPV]; 
    [self configEvents];
}
#pragma mark PVConfig - - - -
+ (void)configPV{ 
    for (NSString *vcName in [JKUBS shareInstance].configureData[JKUBSPVKey]) { 
        Class target = NSClassFromString(vcName);
         [target aspect_hookSelector:@selector(viewDidAppear:) 
                         withOptions:AspectPositionAfter 
                          usingBlock:^(id data){ 
                              [self JKhandlePV:data status:JKUBSPV_ENTER]; 
                          } error:nil ];
     [target aspect_hookSelector:@selector(viewDidDisappear:) 
                    withOptions:AspectPositionAfter 
                     usingBlock:^(id data){
                         [self JKhandlePV:data status:JKUBSPV_LEAVE]; 
                     } error:nil ]; 
    }
}

+ (void)JKhandlePV:(id<AspectInfo>)data status:(JKUBSPVSTATUS)status{
}

#pragma mark EventConfig - - - -
+ (void)configEvents{ 
    NSDictionary *eventsDic = [JKUBS shareInstance].configureData[JKUBSEventKey]; 
    NSArray *events =[eventsDic allValues]; 
    for (NSDictionary *dic in events) { 
        NSInteger EventID = [dic[JKUBSEventIDKey] integerValue]; 
        NSArray *eventConfigs = [dic[JKUBSEventConfigKey] allValues]; 
        for (NSDictionary *eventConfig in eventConfigs) { 
            NSString *selectorStr = eventConfig[JKUBSSelectorStrKey]; 
            NSString *targetClass = eventConfig[JKUBSTargetKey]; 
            Class target = NSClassFromString(targetClass); 
            SEL selector = NSSelectorFromString(selectorStr); 
            [target aspect_hookSelector:selector 
                            withOptions:AspectPositionBefore 
                             usingBlock:^(id<AspectInfo> data){ 
                                [self JKHandleEvent:data EventID:EventID]; 
                             } error:nil ];
        } 
    }
}

+ (void)JKHandleEvent:(id<AspectInfo>)data EventID:(NSInteger)eventId{

}

2.5 引用其他的 Makefile

语法: include <filename>  (filename 可以分包通配符和路线)

示例:

# Makefile 内容
all:
    @echo "主 Makefile begin"
    @make other-all
    @echo "主 Makefile end"

include ./other/Makefile

# ./other/Makefile 内容
other-all:
    @echo "other makefile begin"
    @echo "other makefile end"

# bash中执行 make
$ ll
total 20K
-rw-r--r-- 1 wangyubin wangyubin  125 Sep 23 16:13 Makefile
-rw-r--r-- 1 wangyubin wangyubin  11K Sep 23 16:15 makefile.org   <-- 这个文件不用管
drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 23 16:11 other
$ ll other/
total 4.0K
-rw-r--r-- 1 wangyubin wangyubin 71 Sep 23 16:11 Makefile

$ make
主 Makefile begin
make[1]: Entering directory `/path/to/test/makefile'
other makefile begin
other makefile end
make[1]: Leaving directory `/path/to/test/makefile'
主 Makefile end

 

用户作为统计统计什么?
  我们常常说用户作为统计,那么用户作为统计要统什计么呢,在我看来主要分为两类:
1,页面统计:PV2,事件统计:Event
  页面统计:PV
  页面统计就是就于用户进入某页面的时候,进记行录保存;在用户距离某个页面的时刻进行保存记录。在当适的早晚以保留之多少发送给后台服务器。实现代码如下:

2.7 make 退出码

Makefile的退出码有以下3种植:

  • 0 :: 表示成功推行
  • 1 :: 表示make命令出现了左
  • 2 :: 使用了 “-q” 选项, 并且make使得一些靶不需更新

 

1,并不是所有的事件都是有继承自UIControl的空间来发出的,比如:手势,点击Cell。
2,并不是所有的按钮点击了之后就立马需要埋点上传?可能在按钮的响应方法中经过了层层的if(){ } else{ }最后才需要埋点。
3,对于代理方法该怎样处理?
4,如果很多个按钮对应着一个事件该怎样处理?

3.4.4 if

这边的if是个函数, 和前的法判断不雷同,
前面的规则判断属于Makefile的关键字

语法:

$(if <condition>,<then-part>)

$(if <condition>,<then-part>,<else-part>)

 

示例:

# Makefile 内容
val := a
objects := $(if $(val),$(val).o,nothing)
no-objects := $(if $(no-val),$(val).o,nothing)

all:
    @echo $(objects)
    @echo $(no-objects)

# bash 中执行 make
$ make
a.o
nothing

 

有的是博客贴出这样的代码以为就是缓解了问题,其实忽略了非常老之一个问题,这样简粗单暴的错过处理,会发觉项中目所的起UIViewCnotroller的及时半个道viewDidAppear:,viewDidDisappear:都于会hook,造了成额外之属性开销,非常的不得了。所以我穷尽立进行了处理就针对要统的计页面进行hook操作。具现体实如下:

2.11.1 命令变量, 书写Makefile可以一直写 shell时用这些变量.

下面就排有一些C相关的

变量名

含义

RM rm -f
AR ar
CC cc
CXX g++

示例:

# Makefile 内容
all:
    @echo $(RM)
    @echo $(AR)
    @echo $(CC)
    @echo $(CXX)

# bash 中执行make, 显示各个变量的值
$ make
rm -f
ar
cc
g++

 

对手势触发的轩然大波进行统计虽然困难,但要促成了。
  对于点击UITableView单元格cell触发的风波,点击UICollectionView单元格cell触发的波。我顿时边坐点击UITableView单元格cell触发的轩然大波也条例进行验证。假设JKBViewController
实现了UITableView
的代理方tableView:didSelectRowAtIndexPath:
这就是说自己的贯彻如下:

2.12 自动变量

Makefile 中过多下经过机关变量来简化书写, 各个机关变量的含义如下:

自动变量

含义

$@ 目标集合
$% 当目标是函数库文件时, 表示其中的目标文件名
$< 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标
$? 比目标新的依赖目标的集合
$^ 所有依赖目标的集合, 会去除重复的依赖目标
$+ 所有依赖目标的集合, 不会去除重复的依赖目标
$* 这个是GNU make特有的, 其它的make不一定支持

 

+ (void)configUIControlEvent{

    [UIControl aspect_hookSelector:@selector(sendAction:to:forEvent:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> data){
        [self JKHandleEvent:data];
    } error:nil];

}

3.4.7 shell

语法:

$(shell <shell command>)

它的企图就是是推行一个shell命令, 并将shell命令的结果当函数的返回.

作用和 `<shell command>` 一样, ` 是倒引号

 

大家好看出PV字段下,每一个页面还归因于可安装页面的名字,还同有头其它的信。
Event字段下出EventID,同时也吗允许和一个EventID下发生两样之触发事件。
事件1
随即一级字段写及具体的事件始末,主要是有益开发人读员阅查找。
JKVC1点碰碰,JKVC2接触碰碰,tap单击,选中tableView单元格这些都是为了标件来明事源,方便开发人员阅读。另外如事件还需安排额外的参数,那么好当EventID同级字段下上加新的始末。
下看看面来代码吧:
JKUBS.h

3.4.3 foreach

语法:

$(foreach <var>,<list>,<text>)

 

示例:

# Makefile 内容
targets := a b c d
objects := $(foreach i,$(targets),$(i).o)

all:
    @echo $(targets)
    @echo $(objects)

# bash 中执行 make
$ make
a b c d
a.o b.o c.o d.o

 

这个实现起来相对容易些,相信大家还发出落实了。
  对UIGestureRecognizer
点的事件进行拍卖,比较麻烦 首先UIGestureRecognizer
凡一个类簇,我们接触事件时的tap,LongPress,swipe,pan等手势发送事件是并无是殡葬事件的审的切近,我立马边经过打断点的样式找到了发送事件的实在的类似是:UIGestureRecognizerTarget
出殡事件的私有方法是:_sendActionWithGestureRecognizer:
然后自己便通过hook操作对手势触发的风波进展了处理:

1.1 Makefile 主要的 5个组成部分 (显示规则, 隐晦规则, 变量定义, 文件指示, 注释)

Makefile基本格式如下:

target ... : prerequisites ...
    command
    ...
    ...

其中,

  • target        – 目标文件, 可以是 Object File, 也足以是可执行文件
  • prerequisites – 生成 target 所待的文本或者目标
  • command       – make需要执行的命令 (任意的shell命令),
    Makefile中之指令必须坐 [tab] 开头

 

  1. 显规则 :: 说明什么充分成一个还是多只目标文件(包括 生成的文本,
    文件的因文件, 生成的一声令下)
  2. 隐晦规则 :: make的机动推导功能所执的平整
  3. 变量定义 :: Makefile中定义的变量
  4. 文本指示 :: Makefile中援其他Makefile; 指定Makefile中有效组成部分;
    定义一个基本上尽命令
  5. 注解     :: Makefile只发尽注释 “#”, 如果要用要输出”#”字符,
    需要展开转义, “\#”

 

JKUBS.m

3.2 定义命令包

一声令下包有点像是个函数, 将连的一致的下令合成一长长的, 减少 Makefile
中之代码量, 便于以后维护.

语法:

define <command-name>
command
...
endef

 

示例:

# Makefile 内容
define run-hello-makefile
@echo -n "Hello"
@echo " Makefile!"
@echo "这里可以执行多条 Shell 命令!"
endef

all:
    $(run-hello-makefile)


# bash 中运行make
$ make
Hello Makefile!
这里可以执行多条 Shell 命令!

 

#import <Foundation/Foundation.h>
#import "Aspects.h"

extern NSString const *JKUBSPVKey;
extern NSString const *JKUBSEventKey;
extern NSString const *JKUBSEventIDKey;
extern NSString const *JKUBSEventConfigKey;
extern NSString const *JKUBSSelectorStrKey;
extern NSString const *JKUBSTargetKey;
typedef NS_ENUM(NSInteger, JKUBSPVSTATUS){ 
        JKUBSPV_ENTER = 0, //进入页面 JKUBSPV_LEAVE //离开页面
};

@interface JKUBS : NSObject
@property (nonatomic,strong,readonly) NSDictionary *configureData;
/** 
  生成单例的方法 @return 单例对象 
*/
+ (instancetype)shareInstance;
/** 
  通过json配置文件导入配置信息json配置文件
  或plist配置文件只导入一个就好了 @param jsonFilePath json文件沙盒路径 
*/
+ (void)configureDataWithJSONFile:(NSString *)jsonFilePath;
/** 
  通过plist配置文件导入配置信息json配置文件或plist配置文件只导入一个就好了 
  @param plistFileName plist文件名字(不带后缀名) 
*/
+ (void)configureDataWithPlistFile:(NSString *)plistFileName;
/** 
  处理PV这个方法需要开发者重载进行具体的操作 
  @param data 页面信息 @param status 进入或离开页面的状态 
*/
+ (void)JKhandlePV:(id<AspectInfo>)data status:(JKUBSPVSTATUS)status;
/** 
  处理事件这个方法需要开发者重载进行具体的操作 
  @param data 事件信息 
  @param eventId 事件ID 
*/
+ (void)JKHandleEvent:(id<AspectInfo>)data EventID:(NSInteger)eventId;

@end

2.1.2 规则中之通配符

  • *     :: 表示任意一个或多只字符
  • ?     :: 表示任意一个字符
  • […] :: ex. [abcd] 表示a,b,c,d中任意一个字符,
    [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中随意一个数字
  • ~     :: 表示用户的home目录

 

3. Makefile 高级语法

2.1.3 路径搜索

当一个Makefile中干到大方源文件时(这些自文件与Makefile极生或不在与一个目中),

这儿, 最好用来自文件之路径明确在Makefile中, 便于编译时查找.
Makefile中发出个特殊的变量 VPATH
就是完结这功能的.

指定了 VPATH 之后,
如果当前目录中莫找到相应文件或者凭的文件, Makefile 回到 VPATH 指定的途径中再失查找..

VPATH 使用办法:

  • vpath <directories>            :: 当前目录中查找不顶文件时,
    就由<directories>中检索
  • vpath <pattern> <directories>  ::
    符合<pattern>格式的文本, 就从<directories>中摸索
  • vpath <pattern>                ::
    清除符合<pattern>格式的文本搜索路径
  • vpath                          :: 清除所有曾经安装好之文本路径

 

# 示例1 - 当前目录中找不到文件时, 按顺序从 src目录 ../parent-dir目录中查找文件
VPATH src:../parent-dir   

# 示例2 - .h结尾的文件都从 ./header 目录中查找
VPATH %.h ./header

# 示例3 - 清除示例2中设置的规则
VPATH %.h

# 示例4 - 清除所有VPATH的设置
VPATH

 

1. Makefile 简介

Makefile 是跟 make 命令并配合使用的.

群大型项目的编译都是经 Makefile 来组织的, 如果没有 Makefile,
那许多型遭到各种库以及代码之间的乘关系不知会多复杂.

Makefile的团组织流程的能力如此之高, 不仅可以为此来编译项目,
还可以就此来组织我们平常的片习以为常操作. 这个要大家发表好之想象力.

 

本篇博客是因 {精华} 跟自己旅写
Makefile
而规整的, 有些删减, 追加了有的示例.

非常感谢 gunguymadman_cu 提供这样详细的Makefile介绍,
这正是自己一直找的Makefile中文文档.

 

2.1 Makefile 规则

2.2 Makefile 中之变量

3.3 条件判断

标准判断的要害字主要有 ifeq ifneq ifdef ifndef

语法:

<conditional-directive>
<text-if-true>
endif

# 或者
<conditional-directive>
<text-if-true>
else
<text-if-false>
endif

 

示例: ifeq的例证, ifneq和ifeq的动方法类似, 就是取反

# Makefile 内容
all:
ifeq ("aa", "bb")
    @echo "equal"
else
    @echo "not equal"
endif

# bash 中执行 make
$ make
not equal

 

示例: ifdef的例证, ifndef和ifdef的采取方法类似, 就是取反

# Makefile 内容
SRCS := program.c

all:
ifdef SRCS
    @echo $(SRCS)
else
    @echo "no SRCS"
endif

# bash 中执行 make
$ make
program.c

 

2.2.1 变量定义 ( = or := )

OBJS = programA.o programB.o
OBJS-ADD = $(OBJS) programC.o
# 或者
OBJS := programA.o programB.o
OBJS-ADD := $(OBJS) programC.o

里 = 和 := 的分在, := 只能采用前定义好的变量, =
可以采取后定义的变量

测试 =

# Makefile内容
OBJS2 = $(OBJS1) programC.o
OBJS1 = programA.o programB.o

all:
    @echo $(OBJS2)

# bash中执行 make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使用
$ make
programA.o programB.o programC.o

 

测试 :=

# Makefile内容
OBJS2 := $(OBJS1) programC.o
OBJS1 := programA.o programB.o

all:
    @echo $(OBJS2)

# bash中执行 make, 可以看出 OBJS2 中的 $(OBJS1) 为空
$ make
programC.o

 

3.4 Makefile 中之函数

Makefile 中由带了有的函数, 利用这些函数可以简化 Makefile 的编写.

函数调用语法如下:

$(<function> <arguments>)
# 或者
${<function> <arguments>}
  • <function> 是函数叫做
  • <arguments> 是函数参数

 

2.6 查看C文件的依靠关系

描绘 Makefile 的时段, 需要规定每个目标的依关系.

GNU提供一个建制得以查看C代码文件指那些文件, 这样我们当写 Makefile
目标的时光便毫无打开C源码来拘禁那个负那些文件了.

比如, 下面发号施令显示内核源码中 virt/kvm/kvm_main.c 中的借助关系

$ cd virt/kvm/
$ gcc -MM kvm_main.c 
kvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h   <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系

 

3.4.8 make 控制函数

起一个致命错误: $(error <text …>)

成效: 输出错误信息, 停止Makefile的运行

# Makefile 内容
all:
    $(error there is an error!)
    @echo "这里不会执行!"

# bash 中执行 make
$ make
Makefile:2: *** there is an error!.  Stop.

 

出口警告: $(warning <text …>)

职能: 输出警告信息, Makefile继续运行

# Makefile 内容
all:
    $(warning there is an warning!)
    @echo "这里会执行!"

# bash 中执行 make
$ make
Makefile:2: there is an warning!
这里会执行!

 

2. Makefile 初级语法

1.2 GNU make 的劳作措施

  1. 读入主Makefile (主Makefile中得以引用其他Makefile)
  2. 读入被include的其他Makefile
  3. 初始化文件被的变量
  4. 演绎隐晦规则, 并分析有规则
  5. 呢拥有的靶子文件创建依赖关系链
  6. 根据依赖关系, 决定如何目标一旦双重转
  7. 实施生成命令

 

2.3 Makefile 命令前缀

Makefile 中书shell命令时方可加2种前缀 @ 和 -, 或者不用前缀.

3栽格式的shell命令区别如下:

  • 莫用前缀 :: 输出执行之命令和令执行之结果, 出错的言辞停止实施
  • 前面缀 @   :: 只输出命令执行之结果, 出错的语句停止执行
  • 面前缀 –   :: 命令执行有错的话, 忽略错误, 继续执行

 

示例:

# Makefile 内容 (不用前缀)
all:
    echo "没有前缀"
    cat this_file_not_exist
    echo "错误之后的命令"       <-- 这条命令不会被执行

# bash中执行 make
$ make
echo "没有前缀"             <-- 命令本身显示出来
没有前缀                    <-- 命令执行结果显示出来
cat this_file_not_exist
cat: this_file_not_exist: No such file or directory
make: *** [all] Error 1

###########################################################

# Makefile 内容 (前缀 @)
all:
    @echo "没有前缀"
    @cat this_file_not_exist
    @echo "错误之后的命令"       <-- 这条命令不会被执行

# bash中执行 make
$ make
没有前缀                         <-- 只有命令执行的结果, 不显示命令本身
cat: this_file_not_exist: No such file or directory
make: *** [all] Error 1

###########################################################

# Makefile 内容 (前缀 -)
all:
    -echo "没有前缀"
    -cat this_file_not_exist
    -echo "错误之后的命令"       <-- 这条命令会被执行

# bash中执行 make
$ make
echo "没有前缀"             <-- 命令本身显示出来
没有前缀                    <-- 命令执行结果显示出来
cat this_file_not_exist
cat: this_file_not_exist: No such file or directory
make: [all] Error 1 (ignored)
echo "错误之后的命令"       <-- 出错之后的命令也会显示
错误之后的命令              <-- 出错之后的命令也会执行

 

2.11.2 命令参数变量

变量名

含义

ARFLAGS AR命令的参数
CFLAGS C语言编译器的参数
CXXFLAGS C++语言编译器的参数

 

演示: 下面坐 CFLAGS 为例演示

# test.c 内容
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf ("Hello Makefile\n");
    return 0;
}

# Makefile 内容
test: test.o
    $(CC) -o test test.o

# bash 中用 make 来测试
$ ll
total 24K
-rw-r--r-- 1 wangyubin wangyubin  69 Sep 23 17:31 Makefile
-rw-r--r-- 1 wangyubin wangyubin 14K Sep 23 19:51 makefile.org   <-- 请忽略这个文件
-rw-r--r-- 1 wangyubin wangyubin 392 Sep 23 17:31 test.c

$ make
cc    -c -o test.o test.c
cc -o test test.o               <-- 这个是自动推导的

$ rm -f test test.o

$ make CFLAGS=-Wall             <-- 命令中加的编译器参数自动追加入下面的编译中了
cc -Wall   -c -o test.o test.c
cc -o test test.o

 

3.4.6 origin – 判断变量的来

语法:

$(origin <variable>)

归来值有如下类型:

类型

含义

undefined <variable> 没有定义过
default <variable> 是个默认的定义, 比如 CC 变量
environment <variable> 是个环境变量, 并且 make时没有使用 -e 参数
file <variable> 定义在Makefile中
command line <variable> 定义在命令行中
override <variable> 被 override 重新定义过
automatic <variable> 是自动化变量

 

示例:

# Makefile 内容
val-in-file := test-file
override val-override := test-override

all:
    @echo $(origin not-define)    # not-define 没有定义
    @echo $(origin CC)            # CC 是Makefile默认定义的变量
    @echo $(origin PATH)         # PATH 是 bash 环境变量
    @echo $(origin val-in-file)    # 此Makefile中定义的变量
    @echo $(origin val-in-cmd)    # 这个变量会加在 make 的参数中
    @echo $(origin val-override) # 此Makefile中定义的override变量
    @echo $(origin @)             # 自动变量, 具体前面的介绍

# bash 中执行 make
$ make val-in-cmd=val-cmd
undefined
default
environment
file
command line
override
automatic

 

2.11 分包规则中之 命令变量 和 命令参数变量