Discover相关笔记

#Discover

  • 获取选择的城市

1
2
3
4
5
6
7
8
9
10
theCityArray = [[NSMutableArray alloc] initWithCapacity:10];
[ServiceRouter requestHotCities:0.
                          longitude:0.
                              block:^(RequestResultType type,NSArray* cityArray){
                                  if (REQUEST_SUCCEEDED(type)) {
                                      [temArray addObjectsFromArray:cityArray];
                                  }
                                  
                              }];
  • 在地图的Delegate回调中禁用LocationManager中事件更新

    否则会造成updatelocation方法一直回调,虽然在后面的call api之前被滤掉了,但是mapview的delegate方法一直回调,徒增耗电量。
  • 搜索功能

    相对独立,只是搜索地址,点击后跳转到搜索的地点上。
  • 时光机 复用之前的逻辑

    点击按钮后弹出时光机的选项
  • 点击定位当前

    locationmanager中的方法的触发,获得位置回调后调用方法停止

  • ##手指移动地图

    平移、 对角线移动

    产品给出的是屏幕移动3/4后才开始请求

移动可能会造成中心的点的变化,通过取对角线的中点和上次中点的变化,可以判断是否发生了变化。如果只对中心点进行放大缩小,中心点的位置就没有变化,这个时候再结合地图中的span属性进行判断就能判断是缩放还是平移了。这里总体上面还是迁移原来老的逻辑。

  • 缩放

    放大缩小每次都是上次的一个比值,1/1.2 1*1.2,rate = 1.2
    无论何种移动,都是在regionDidChanged回调方法中去处理

  • Workflow
    1,Discover 首次加载的时候调用定位locationmanager的starlocate方法,获取到位置后停止。viewDidload之前设置了一个默认的地址及北京,然后在开始进行location current的地址回调方法。

    首次定位无论如何都去发送网络请求(之前的代码逻辑中有个bool值用于判断,是否是首次请求,重构过程中可以考虑是否还用这个标识)。

2,缩放每次都进行网络请求
3,移动过程中之前的判断是经度、或者纬度发生变化是0.001的差值时候才发生网络请求。

Charles如何抓取https数据包的

Swiftweekly

  • ####Span的解释

    大概意思就是span表示的是regoin的范围。它有两个字段一个是latitudeDelta,表示纬度范围,南纬和北纬加一起应该有180度,所以它的范围应该是大于0度,小于等于180度;另一个是longitudeDelta,表示经度范围,东经和西经加一起应该有360度,所以它的范围应该是大于0度,小于360度。看完了上面的解释其实还不是很理解,需要用代码来验证一下上面的解释。那我就举一个例子,让地图正好显示中国地图全部。我们先来看看中国地图的经纬度范围,百度搜索“中国经纬度范围”,得出如下结果。

参考链接

*对象引用关联比如给AlertView添加一个东西

通过runtime来添加类变量的方式并不是Category的功劳,objc_setAssociatedObject 和 objc_getAssociatedObject在任何类型的类里都可以把一个变量绑定个一个对象,实际上起到的是一种绑定对象传值的作用,但这并不是说通过Category是能添加变量的,严格意义上来讲单纯的通过Category是不能的,只能说runtime和Category两者结合着还实现的。runtime并不属于Category的功能范畴

1
2
3
4
5
6
@interface Teacher : NSObject
{
NSUInteger age;
}
@end

光有个年龄还不能满足对teacher的描述,我想加个profession实例来存teacher的专业。直观的想法是子类化Teacher,其实也可以用类别。
你需要了解一下 runtime 编程知识,关注一下 objc_setAssociatedObject 和 objc_getAssociatedObject 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Teacher+Profession.m
//
#import "Teacher+Profession.h"
#import <objc/runtime.h>
const char *ProfessionType = "NSString *";
@implementation Teacher (Profession)
-(void)setProf:(NSString*)prof
{
objc_setAssociatedObject(self, ProfessionType, prof, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)prof
{
NSString *pro = objc_getAssociatedObject(self, ProfessionType);
return pro;
}

现在就可以通过setProf: 和 prof 来存取 teacher 的 profession 值了。

/
消息转发要点
/
如图所示

从上面我们可以发现,在发消息的时候,如果 selector 有对应的 IMP ,则直接执行,如果没有,oc 给我们提供了几个可供补救的机会,依次有

  • resolveInstanceMethod 、
  • forwardingTargetForSelector、
  • forwardInvocation。
    Aspects 之所以选择在 forwardInvocation 这里处理是因为,这几个阶段特性都不太一样:resolvedInstanceMethod 适合给类/对象动态添加一个相应的实现,
    forwardingTargetForSelector 适合将消息转发给其他对象处理,
    相对而言,forwardInvocation 是里面最灵活,最能符合需求的。
    因此 Aspects 的方案就是,对于待 hook 的 selector,将其指向 objc_msgForward / _objc_msgForward_stret ,同时生成一个新的 aliasSelector 指向原来的 IMP,并且 hook 住 forwardInvocation 函数,使他指向自己的实现。按照上面的思路,当被 hook 的 selector 被执行的时候,首先根据 selector 找到了 objc_msgForward / _objc_msgForward_stret ,而这个会触发消息转发,从而进入 forwardInvocation。同时由于 forwardInvocation 的指向也被修改了,因此会转入新的 forwardInvocation 函数,在里面执行需要嵌入的附加代码,完成之后,再转回原来的 IMP。