• 触摸事件

  因为 UIView 是 UIResponder 的子类,所以覆盖以下四个方法就可以处理四种不同的触摸事件:

  1.  一根手指或多根手指触摸屏幕

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;

  2.  一根手指或多根手指在屏幕上移动(随着手指的移动,相关的对象会持续发送该消息)

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;

  3.  一根手指或者多根手指离开屏幕

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;

  4.  在触摸操作正常结束前,某个系统事件(例如电话进来)打断了触摸过程

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;

  当系统检测到手指触摸屏幕的事件后,就会创建 UITouch 对象(一根手指的触摸事件对应一个 UITouch 对象)。发生触摸事件的 UIView 对象会收到  touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event 消息,系统传入的第一个实参  touches (NSSet 对象)会包含所有相关的 UITouch 对象。

  当手指在屏幕上移动的时候,系统会更新相应的 UITouch 对象,为其重新设置对应的手指在屏幕上的位置。最初发生触摸事件的那个 UIView 对象会收到  touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event 消息,系统传入的第一个实参  touches (NSSet 对象)会包含所有相关的 UITouch 对象,而且这些 UITouch 对象都是最初发生触摸事件时创造的。

  当手指离开屏幕的时候,系统会最后一个更新相应的 UITouch 对象,为其重新设置对应的手指在屏幕上的位置。接着,最初发生该触摸事件的视图会收到  touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event 消息。当收到该消息并执行完成之后,系统就会释放和当前事件有关的 UITouch 对象。

  下面对 UITouch 对象和事件响应方法的工作机制做一个归纳。

  1.  一个 UITouch 对象对应屏幕上的一根手指。只要手指没有离开屏幕,相应的 UITouch 对象就会一直存在。这些 UITouch 兑现都会保存对应的手指在屏幕上当前的位置。

  2.  在触摸事件的持续过程中,无论发生什么,最初发生触摸事件的那个视图都会在各个阶段收到相应的触摸事件消息。即使手指在移动时离开了这个视图的frame区域,系统还是会向该视图发送  touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event  和  touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event 消息。也就是说,当某个视图发生触摸事件之后,该视图将永远“拥有”当时创建的所有 UITouch 对象。

  3.  我们自己编写的代码不需要保存任何 UITouch 对象。当某个 UITouch 对象的状态发生变化时,系统会向指定的对象发送特定的时间消息,并传入发生变化的 UITouch 对象。

  当应用发生某个触摸事件后(例如触摸开始、手指一动、触摸结束),系统都会将该事件添加至一个由 UIApplication 单例管理的事件队列。通常情况下,很少会出现满队列的情况,所以 UIApplication 会立刻分发队列中的事件。分发某个触摸事件时,UIApplication 会向 “拥有” 该事件的视图发送特定的 UIResponder 消息。

  当多根手指在同一个视图、同一个时刻执行相同的触摸动作时,UIApplication 会用单个消、一次分发所有的 UITouch 对象。UIApplication 在发送特定的UIResponder 消息时,会传入一个 NSSet 对象,该对象将包含所有相关的 UITouch 对象(一个 UITouch 对象对应一根手指)。但是,因为 UIApplication 对 “同一时刻”的判断很严格,所以通常情况下,哪怕是一组事件都是在很短的一段时间内发生的,UIApplication 也会发送多个 UIResponder 消息,分批发送 UITouch 对象。

  • 创建 JXTouchTracker 应用

  首先,JXTouchTracker 需要一个能够描述线条的模型对象。创建一个新的 JXLine 子类。声明两个 CGPoint 属性。

#import <UIKit/UIKit.h>

@interface JXLine : NSObject
/** 开始位置 */
@property (nonatomic,assign) CGPoint begin;
/** 结束位置 */
@property (nonatomic,assign) CGPoint end;
@end
#import "JXLine.h"

@implementation JXLine

@end

  接着,创建一个新的自定义类。

#import <UIKit/UIKit.h>

@interface JXDrawView : UIView

@end
#import "JXDrawView.h"

@implementation JXDrawView

@end

  下面创建一个 UIViewController 子类,用于管理 JXDrawView 对象。

#import <UIKit/UIKit.h>

@interface JXDrawViewController : UIViewController

@end
#import "JXDrawViewController.h"

@interface JXDrawViewController ()

@end

@implementation JXDrawViewController

- (void)viewDidLoad {
[super viewDidLoad]; } @end

  接下来

#import "AppDelegate.h"
#import "JXDrawViewController.h"

@interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; JXDrawViewController * drawController = [[JXDrawViewController alloc] init];
self.window.rootViewController = drawController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}

  在 JXDrawViewController 中覆盖  loadView 方法,创建一个 JXDrawView 对象并将其赋值给 JXDrawViewController 对象的  view 属性

#import "JXDrawViewController.h"
#import "JXDrawView.h"

@interface JXDrawViewController () @end @implementation JXDrawViewController
- (void)loadView {
self.view = [[JXDrawView alloc] initWithFrame:CGRectZero];
}
- (void)viewDidLoad {
[super viewDidLoad]; } @end
  • 实现 JXDrawView 完成绘图功能

  JXDrawView 对象需要管理正在绘制的线条和绘制完成的线条。

#import "JXDrawView.h"
#import "JXLine.h"

@interface JXDrawView ()
/** 保存当前正在绘制线条 */
@property (nonatomic,strong) JXLine * currentLine;
/** 保存已经绘制完成的线条 */
@property (nonatomic,strong) NSMutableArray * finishedLines;
@end @implementation JXDrawView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.finishedLines = [NSMutableArray array];
self.backgroundColor = [UIColor grayColor];
}
return self;
}
@end

  接下来需要编写绘制线条的代码。

#import "JXDrawView.h"
#import "JXLine.h" @interface JXDrawView ()
/** 保存当前正在绘制线条 */
@property (nonatomic,strong) JXLine * currentLine;
/** 保存已经绘制完成的线条 */
@property (nonatomic,strong) NSMutableArray * finishedLines; @end @implementation JXDrawView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.finishedLines = [NSMutableArray array];
self.backgroundColor = [UIColor grayColor];
}
return self;
} - (void)strokeLine:(JXLine *)line {
UIBezierPath * bp = [UIBezierPath bezierPath];
bp.lineWidth = ;
bp.lineCapStyle = kCGLineCapRound; [bp moveToPoint:line.begin];
[bp addLineToPoint:line.end];
[bp stroke];
} - (void)drawRect:(CGRect)rect {
// 用黑色表示已经绘制完成的线条
[[UIColor blackColor] set];
for (JXLine * line in self.finishedLines) {
[self strokeLine:line];
} if (self.currentLine) {
// 用红色表示当前正在绘制的线条
[[UIColor redColor] set];
[self strokeLine:self.currentLine];
}
}
@end
  • 处理触摸事件并创建线条对象

  这里我们只创建直线,所以我们需要用 JXLine 的 begin  和  end  属性来保存这两个点。当触摸事件开始时,JXDrawView 对象需要创建一个 JXLine 对象,并将其两个属性都设置为触摸发生时的位置。当触摸事件继续时,JXDrawView 对象要将  end  属性设置为手指当前位置。当触摸结束时,这个 JXLine 对象就能代表完成后的线条。

#import "JXDrawView.h"
#import "JXLine.h" @interface JXDrawView ()
/** 保存当前正在绘制线条 */
@property (nonatomic,strong) JXLine * currentLine;
/** 保存已经绘制完成的线条 */
@property (nonatomic,strong) NSMutableArray * finishedLines; @end @implementation JXDrawView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.finishedLines = [NSMutableArray array];
self.backgroundColor = [UIColor grayColor];
}
return self;
} - (void)strokeLine:(JXLine *)line {
UIBezierPath * bp = [UIBezierPath bezierPath];
bp.lineWidth = ;
bp.lineCapStyle = kCGLineCapRound; [bp moveToPoint:line.begin];
[bp addLineToPoint:line.end];
[bp stroke];
} - (void)drawRect:(CGRect)rect {
// 用黑色表示已经绘制完成的线条
[[UIColor blackColor] set];
for (JXLine * line in self.finishedLines) {
[self strokeLine:line];
} if (self.currentLine) {
// 用红色表示当前正在绘制的线条
[[UIColor redColor] set];
[self strokeLine:self.currentLine];
}
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch * t = [touches anyObject]; // 根据触摸位置创建 JXLine 对象
CGPoint location = [t locationInView:self];
self.currentLine = [[JXLine alloc] init];
self.currentLine.begin = location;
self.currentLine.end = location; [self setNeedsDisplay];
} - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch * t = [touches anyObject]; CGPoint location = [t locationInView:self]; self.currentLine.end = location; [self setNeedsDisplay];
} - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.finishedLines addObject:self.currentLine];
self.currentLine = nil;
[self setNeedsDisplay];
}
@end

  

  多点触摸

  默认情况下,视图在同一时刻只能接收一个触摸事件。如果一个手指已经触发了 touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 方法,那么在手指离开前,其他触摸事件都会被忽略。

  为了使 JXDrawView 同时接受多个触摸事件,我们需要额外的处理。

#import "JXDrawView.h"
#import "JXLine.h" @interface JXDrawView ()
/** 保存当前正在绘制线条 */
@property (nonatomic,strong) JXLine * currentLine;
/** 保存已经绘制完成的线条 */
@property (nonatomic,strong) NSMutableArray * finishedLines; @end @implementation JXDrawView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.finishedLines = [NSMutableArray array];
self.backgroundColor = [UIColor grayColor]; // 支持多点触摸
self.multipleTouchEnabled =
YES;
}
return self;
} - (void)strokeLine:(JXLine *)line {
UIBezierPath * bp = [UIBezierPath bezierPath];
bp.lineWidth = ;
bp.lineCapStyle = kCGLineCapRound; [bp moveToPoint:line.begin];
[bp addLineToPoint:line.end];
[bp stroke];
} - (void)drawRect:(CGRect)rect {
// 用黑色表示已经绘制完成的线条
[[UIColor blackColor] set];
for (JXLine * line in self.finishedLines) {
[self strokeLine:line];
} if (self.currentLine) {
// 用红色表示当前正在绘制的线条
[[UIColor redColor] set];
[self strokeLine:self.currentLine];
}
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch * t = [touches anyObject]; // 根据触摸位置创建 JXLine 对象
CGPoint location = [t locationInView:self];
self.currentLine = [[JXLine alloc] init];
self.currentLine.begin = location;
self.currentLine.end = location; [self setNeedsDisplay];
} - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch * t = [touches anyObject]; CGPoint location = [t locationInView:self]; self.currentLine.end = location; [self setNeedsDisplay];
} - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.finishedLines addObject:self.currentLine];
self.currentLine = nil;
[self setNeedsDisplay];
}
@end

  现在当多根手指在屏幕上触摸、移动、离开时, JXDrawView 都将会收到相应的 UIResponder 消息。但是现有代码并不能正确处理这些消息:现在我们目前的代码只能处理一个触摸消息。

  之前实现的触摸方法中,代码向 NSSet 类型的一个  touches 发送了  anyObject 消息-在只能接收单点触摸的视图中, touches 在同一时刻只会包含一个触摸事件,因此  anyObject 可以正确返回唯一的触摸事件。但是在可以接收多点触摸的视图中, touches 在同一时刻可能包含一个或者多个触摸事件。

  目前为止,我们的代码中只有一个  currentLine 属性用于保存正在绘制的直线。当有多个触摸事件的时候,我们可能会想多用多个属性来保存正在绘制的直线,但是这样做是绝对不可取的,因为加入我们只移动一根手指的时候,那么我们应该用哪个属性来接收呢?

  所以更好的解决办法就是使用 NSMtableDictionary 对象来保存正在绘制的直线:之前触摸事件时,JXDrawView 可以根据传入的 UITouch 对象创建 JXLine 并将两者关联存储到字典中。

#import "JXDrawView.h"
#import "JXLine.h" @interface JXDrawView ()
/** 保存当前正在绘制线条 */
@property (nonatomic,strong) JXLine * currentLine;
/** 保存已经绘制完成的线条 */
@property (nonatomic,strong) NSMutableArray * finishedLines;
/** 保存正在绘制的多条直线 */
@property (nonatomic,strong) NSMutableDictionary * linesInProgress;
@end @implementation JXDrawView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) { self.linesInProgress = [NSMutableDictionary dictionary];
self.finishedLines = [NSMutableArray array];
self.backgroundColor = [UIColor grayColor]; // 支持多点触摸
self.multipleTouchEnabled = YES;
}
return self;
} - (void)strokeLine:(JXLine *)line {
UIBezierPath * bp = [UIBezierPath bezierPath];
bp.lineWidth = ;
bp.lineCapStyle = kCGLineCapRound; [bp moveToPoint:line.begin];
[bp addLineToPoint:line.end];
[bp stroke];
} - (void)drawRect:(CGRect)rect {
// 用黑色表示已经绘制完成的线条
[[UIColor blackColor] set];
for (JXLine * line in self.finishedLines) {
[self strokeLine:line];
} // 用红色绘制正在画的线条
[[UIColor redColor] set];
for (NSValue * key in self.linesInProgress) {
[self strokeLine:self.linesInProgress[key]];
} if (self.currentLine) {
// 用红色表示当前正在绘制的线条
[[UIColor redColor] set
];
[self strokeLine:self.currentLine];
}

} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch * t = [touches anyObject]; for (UITouch * t in touches) {
CGPoint location = [t locationInView:self]; JXLine * line = [[JXLine alloc] init];
line.begin = location;
line.end = location; NSValue * key = [NSValue valueWithNonretainedObject:t];
self.linesInProgress[key] = line;
} // 根据触摸位置创建 JXLine 对象
CGPoint location = [t locationInView:self];
self.currentLine = [[JXLine alloc] init];
self.currentLine.begin = location;
self.currentLine.end =
location; [self setNeedsDisplay];
} - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { for (UITouch * t in touches) {
NSValue * key = [NSValue valueWithNonretainedObject:t];
JXLine * line = self.linesInProgress[key];
line.end = [t locationInView:self];
} UITouch * t = [touches anyObject]; CGPoint location = [t locationInView:self]; self.currentLine.end =
location; [self setNeedsDisplay];
} - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { for (UITouch *t in touches) {
NSValue * key = [NSValue valueWithNonretainedObject:t];
JXLine * line = self.linesInProgress[key]; [self.finishedLines addObject:line];
[self.linesInProgress removeObjectForKey:key];
} [self.finishedLines addObject:self.currentLine];
self.currentLine =
nil;
[self setNeedsDisplay];
}
@end

  最后还需要处理触摸取消事件。如果系统中断了应用,触摸事件将会被取消。这时应该将应用恢复到触摸事件发生前的状态。对于我们的应用来说是需要将正在绘制的线条删除。

#import "JXDrawView.h"
#import "JXLine.h" @interface JXDrawView ()
/** 保存当前正在绘制线条 */
@property (nonatomic,strong) JXLine * currentLine;
/** 保存已经绘制完成的线条 */
@property (nonatomic,strong) NSMutableArray * finishedLines;
/** 保存正在绘制的多条直线 */
@property (nonatomic,strong) NSMutableDictionary * linesInProgress; @end @implementation JXDrawView - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) { self.linesInProgress = [NSMutableDictionary dictionary];
self.finishedLines = [NSMutableArray array];
self.backgroundColor = [UIColor grayColor]; // 支持多点触摸
self.multipleTouchEnabled = YES;
}
return self;
} - (void)strokeLine:(JXLine *)line {
UIBezierPath * bp = [UIBezierPath bezierPath];
bp.lineWidth = ;
bp.lineCapStyle = kCGLineCapRound; [bp moveToPoint:line.begin];
[bp addLineToPoint:line.end];
[bp stroke];
} - (void)drawRect:(CGRect)rect {
// 用黑色表示已经绘制完成的线条
[[UIColor blackColor] set];
for (JXLine * line in self.finishedLines) {
[self strokeLine:line];
} // 用红色绘制正在画的线条
[[UIColor redColor] set];
for (NSValue * key in self.linesInProgress) {
[self strokeLine:self.linesInProgress[key]];
} } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { for (UITouch * t in touches) {
CGPoint location = [t locationInView:self]; JXLine * line = [[JXLine alloc] init];
line.begin = location;
line.end = location; NSValue * key = [NSValue valueWithNonretainedObject:t];
self.linesInProgress[key] = line;
} [self setNeedsDisplay];
} - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { for (UITouch * t in touches) {
NSValue * key = [NSValue valueWithNonretainedObject:t];
JXLine * line = self.linesInProgress[key];
line.end = [t locationInView:self];
} [self setNeedsDisplay];
} - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { for (UITouch *t in touches) {
NSValue * key = [NSValue valueWithNonretainedObject:t];
JXLine * line = self.linesInProgress[key]; [self.finishedLines addObject:line];
[self.linesInProgress removeObjectForKey:key];
} [self setNeedsDisplay];
} - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
for (UITouch *t in touches) {
NSValue * key = [NSValue valueWithNonretainedObject:t];
[self.linesInProgress removeObjectForKey:key];
}
[self setNeedsDisplay];
}
@end
  • 响应链

  UIResponder 对象可以接收触摸事件,而 UIView 是典型的 UIResponder 子类。除了 UIView ,还有很多其他的 UIResponder 子类,其中包括 UIViewController 、 UIApplication 、 UIWindowUIViewController 不是视图对象,也就是无法显示触摸,无法显示,为什么也是 UIResponder 子类呢?因为虽然不能向其直接发送触摸事件,但是该对象能够通过响应链来接收事件。

  UIResponder 对象拥有一个名为  nextResponder 的指针,相关的 UIResponder 对象可以通过该指针组成一个响应链。当 UIView 对象属于某个 UIViewController 对象时,其  nextResponder 指针就会指向包含该视图的 UIViewController 对象。当 UIView 对象不属于任何 UIViewController 对象时,其  nextResponder 指针就会指向该视图的父视图。UIViewController 对象的  nextResponder 通常会指向其视图的父视图。最顶层的父视图是 UIWindow 对象,而 UIWindow 对象的  nextResponder 指向的是 UIApplication 单例。

  如果 UIResponder 对爱国没有处理传给他的事件,会发生什么?该对象会将未处理的消息转发给自己的  nextResponder 。这也是  touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event  这类方法的默认实现。因此,如果没有为某个 UIResponder 对象覆盖特定的事件处理方法,那么该对象的  nextResponder 会尝试处理相应的触摸事件。最终,该事件会传递给 UIApplication ,如果它也无法处理,那么系统就会丢掉该事件。

  这里有一个操作技巧,获取 UIView 自定义文件的控制器

-(UIViewController *)viewcontroller{

    UIResponder *next = [self nextResponder];

    while (next) {

        if ([next isKindOfClass:[UIViewController class]]) {

            return (UIViewController *)next;

        }

        next = [next nextResponder];

    }

    return nil;

}

  项目地址

iOS 触摸事件与UIResponder(内容根据iOS编程编写)的更多相关文章

  1. IOS——触摸事件 视图检测和事件传递

    iPhone上有非常流畅的用户触摸交互体验,能检测各种手势:点击,滑动,放大缩小,旋转.大多数情况都是用UI*GestureRecognizer这样的手势对象来关联手势事件和手势处理函数.也有时候,会 ...

  2. IOS 触摸事件分发机制详解

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:MelonTeam 前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案 ...

  3. IOS触摸事件和手势识别

    IOS触摸事件和手势识别 目录 概述 触摸事件 手势识别 概述 为了实现一些新的需求,我们常常需要给IOS添加触摸事件和手势识别 触摸事件 触摸事件的四种方法 -(void)touchesBegan: ...

  4. 【原】iOS触摸事件深度解析

    概述 本文主要解析从我们的手指触摸苹果设备到最终响应事件的整个处理机制.本质上讲,整个过程可以分为两个步骤: 步骤1:找目标.在iOS视图层次结构中找到触摸事件的最终接受者: 步骤2:事件响应.基于i ...

  5. iOS触摸事件深度解析-备用

    概述 本文主要解析从我们的手指触摸苹果设备到最终响应事件的整个处理机制.本质上讲,整个过程可以分为两个步骤: 步骤1:找目标.在iOS视图层次结构中找到触摸事件的最终接受者: 步骤2:事件响应.基于i ...

  6. iOS触摸事件深入

    转载自:http://www.cnblogs.com/wengzilin/p/4720550.html 概述 本文主要解析从我们的手指触摸苹果设备到最终响应事件的整个处理机制.本质上讲,整个过程可以分 ...

  7. iOS 触摸事件与手势识别器(Gesture Recognizers)

    Gesture Recognizers与触摸事件分发 通过一个问题引出今天的知识: 1.大家应该都遇见过 当需要给tableView 添加一个tap 手势识别 但是tableView 的上的事件(滑动 ...

  8. iOS - UIEvent事件及UIResponder响应者

    在iOS中不是所有的对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件,称之为响应者对象: UIApplication.UIViewController.UIView都继承自U ...

  9. 浅谈iOS触摸事件理解

    iOS的触摸事件个人总结,分为两步: 第一步:是找到哪个视图上触摸 第二步:分析由谁去响应(响应者连) 1.寻找被触摸的视图原理如下图 hitText:withEvent:的方法处理流程: 首先会在当 ...

随机推荐

  1. SuperMap iClient for JavaScript 新手入门

    地理信息系统(英语:Geographic Information System,缩写:GIS)是一门综合性学科,结合地理学与地图学,已经广泛的应用在不同的领域,是用于输入.存储.查询.分析和显示地理数 ...

  2. 记录我这一年的技术之路(nodejs纯干货)

    2015年12月28日23:19:54 更新koa应用.学习型网站和开发者工具等 coding伊始 开始认认真真的学习技术还是2015.10.21日开始的,记得很清楚,那天,是我在龙湖正式学习的第一天 ...

  3. 如何利用pt-online-schema-change进行MySQL表的主键变更

    业务运行一段时间,发现原来的主键设置并不合理,这个时候,想变更主键.这种需求在实际生产中还是蛮多的. 下面,看看pt-online-schema-change解决这类问题的处理方式. 首先,创建一张测 ...

  4. pt-online-schema-change中update触发器的bug

    pt-online-schema-change在对表进行表结构变更时,会创建三个触发器. 如下文测试案例中的t2表,表结构如下: mysql> show create table t2\G . ...

  5. peer not authenticated的终极解决方案

    一.前述 使用httpclient发起https请求时,可能会遇到如下异常: javax.net.ssl.SSLPeerUnverifiedException: peer not authentica ...

  6. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  7. linux yum命令详解

    yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RP ...

  8. Linux学习日记-MVC的部署(三)

    一.Mvc与wcf 相对WCF的部署MVC还是有点麻烦,我们要考虑哪些dll是不需要的,哪些是要拷贝到本地的. 而WCF因为有些配置文件不支持,我们只需要在配置wcf时不使用配置文件而直接使用代码就行 ...

  9. 微软.Net 社区虚拟大会 -- 首日重点(dotnetConf 2016)

    6月7日--9日,为期三天的微软.NET社区虚拟大会正式在 Channel9 上召开. 在 Scott Hunter, Miguel de Icaza (Xamarin CTO) , ScottHan ...

  10. 几款主流 NoSql 数据库的对比

    最近小组准备启动一个 node 开源项目,从前端亲和力.大数据下的IO性能.可扩展性几点入手挑选了 NoSql 数据库,但具体使用哪一款产品还需要做一次选型. 我们最终把选项范围缩窄在 HBase.R ...