6 Specialzed layers 特殊层  第一部分  读书笔记

 

Specialization is a feature of every complex organization.

专注是每个复杂系统的特性

Catharine R. Stimpson

 

Up to this point, we have been working with the CALayer class, and we have seen that it has some useful image drawing and transformation capabilities. But Core Animation layers can be used for more than just images and colors. This chapter explores some of the other layer classes that you can use to extend Core Animation's drawing capabilities.

这章我们将研究能用来扩展core animation 绘制能力的的其他
的类。

CAShapeLayer

In Chapter 4, "Visual Effects," you learned how to use CGPath to create arbitrarily shaped shadows without using images. It would be neat if we could create arbitrarily shaped layers in the same way.

 

CAShapeLayer is a layer subclass that draws itself using vector graphics instead of a bitmap image. You specify attributes such as color and line thickness, define the desired shape using a CGPath, and CAShapeLayer renders it automatically.

你指明属性例如 color and line thickness ,用CGPath定义需要的图片,CAShapeLayer自动的把他们显示出来。 

Of course, you could use Core Graphics to draw a path directly into the contents of an ordinary CALayer (as in Chapter 2, "The Backing Image"), but there are several advantages to using CAShapeLayer instead:

你可以使用普通的CALayer,但是使用CAShaperLayer有下列好处:

 

▪ It's fast—CAShapeLayer uses hardware-accelerated drawing and is much faster than using Core Graphics to draw an image.

更快

 

▪ It's memory efficient—A CAShapeLayer does not have to create a backing image like an ordinary CALayer does, so no matter how large it gets, it won't consume much memory.

内存更有效

 

▪ It doesn't  get clipped to the layer bounds—A CAShapeLayer can happily draw outside of its bounds. Your path will not get clipped like it does when you draw into a regular CALayer using Core Graphics (as you saw in Chapter 2).

不会被layer bounds 剪切

 

▪ There's no pixelation  — When you transform a CAShapeLayer by scaling it up or moving it closer to the camera with a 3D perspective transform, it does not become pixelated like an ordinary layer's backing image would.

不会像素失真

 

Creating a CGPath

 

CAShapeLayer can be used to draw any shape that can be represented by a CGPath.

CAShapeLayer 能够绘制任何能用CGPath绘制的形状 

The shape doesn't have to be closed, and the path doesn't have to be unbroken, so you can actually draw several distinct shapes in a single layer. 形状不一定是闭合的,也不一定是不可分割的。

You can control the strokeColor and fillColor of the path, along with other properties such as lineWidth (line thickness, in points), lineCap (how the ends of lines look), and lineJoin (how the joints between lines look); but you can only set these properties once, at the layer level. If you want to draw multiple shapes with different colors or styles, you have to use a separate layer for each shape.

Listing 6.1 shows the code for a simple stick figure drawing, rendered using a single CAShapeLayer. The CAShapeLayer path property is defined as a CGPathRef, but we've created the path using the UIBezierPath helper class, which saves us from having to worry about manually releasing the CGPath. Figure 6.1 shows the result. It's not exactly a Rembrandt, but you get the idea!

Listing 6.1 Drawing a Stick Figure Using CAShapeLayer #import "DrawingView.h"

 

#import <QuartzCore/QuartzCore.h>
@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *containerView;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//create path

 

UIBezierPath *path = [[UIBezierPath alloc] init];

[path moveToPoint:CGPointMake(175, 100)];

 endAngle:2*M_PI

clockwise:YES];
[path moveToPoint:CGPointMake(150, 125)];

 

[path addLineToPoint:CGPointMake(150, 175)];

[path addLineToPoint:CGPointMake(125, 225)];

[path moveToPoint:CGPointMake(150, 175)];

[path addLineToPoint:CGPointMake(175, 225)];

[path moveToPoint:CGPointMake(100, 150)];

[path addLineToPoint:CGPointMake(200, 150)];

//create shape layer

 

CAShapeLayer *shapeLayer = [CAShapeLayer layer];

shapeLayer.strokeColor = [UIColor redColor].CGColor;

shapeLayer.fillColor = [UIColor clearColor].CGColor;

shapeLayer.lineWidth = 5;

 

shapeLayer.lineJoin = kCALineJoinRound;

shapeLayer.lineCap = kCALineCapRound;

shapeLayer.path = path.CGPath;

//add it to our view

[self.containerView.layer addSublayer:shapeLayer]; }

 

@end

Figure 6.1 A simple stick figure displayed using CAShapeLayer

Rounded Corners, Redux

 

Chapter 2 mentioned that CAShapeLayer provides an alternative way to create a view with rounded corners, as opposed to using the CALayer cornerRadius property. Although using a CAShapeLayer is a bit more work, it has the advantage that it allows us to specify the radius of each corner independently.

尽管使用CAShapeLayer有点麻烦,但是可以为每个角独立的指定弧度。

We could create a rounded rectangle path manually using individual straight lines and arcs, but UIBezierPath actually has some convenience constructors for creating rounded rectangles automatically. The following code snippet produces a path with three rounded corners and one sharp:

//define path parameters

 

CGRect rect = CGRectMake(50, 50, 100, 100);

CGSize radii = CGSizeMake(20, 20);

UIRectCorner corners = UIRectCornerTopRight | UIRectCornerBottomRight | UIRectCornerBottomLeft;

//create path

 

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];

 

 

We can use a CAShapeLayer with this path to create a view with mixed sharp and rounded corners.

我们可以利用CAShapeLayer 有这个path来创建一个固定的角度和圆角的view 

If we want to clip the view's contents to this shape, we can use our CAShapeLayer as the mask property of the view's backing layer instead of adding it as a sublayer. (See Chapter 4, "Visual Effects," for a full explanation of layer masks.)

CATextLayer  

 

A user interface cannot be constructed from images alone. A well-designed icon can do a great job of conveying the purpose of a button or control, but sooner or later you're going to need a good old-fashioned text label.

 

 

If you want to display text in a layer, there is nothing stopping you from using the layer delegate to draw a string directly into the layer contents with Core Graphics (which is essentially how UILabel works).

使用layer 代理去绘制一个String 直接到layer 的content是
用Core Graphics . 

This is a cumbersome approach if you are working directly with layers, though, instead of layer-backed views.

如果你想直接与layers工作,而不是在layer-backed views时,会是笨重的方法。

You would need to create a class that can act as the layer delegate for each layer that displays text, and then write logic to determine which layer should display which string, not to mention keeping track of the different fonts, colors, and so on.

 

Fortunately, this is unnecessary. Core Animation provides a subclass of CALayer called CATextLayer that encapsulates most of the string drawing features of UILabel in layer form and adds a few extra features for good measure.

CATextLayer囊括了UILabel string 绘制的特性并添加了一些更好的特色。

CATextLayer also renders much faster than UILabel. It's a little-known fact that on iOS6 and earlier, UILabel actually uses WebKit to do its text drawing, which carries a significant performance overhead when you are drawing a lot of text. CATextLayer uses Core Text and is significantly faster.

Let's try displaying some text using a CATextLayer. Listing 6.2 shows the code to set up and display a CATextLayer, and Figure 6.2 shows the result.

 

Listing 6.2 Implementing a Text Label Using CATextLayer

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *labelView;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//create a text layer

 

CATextLayer *textLayer = [CATextLayer layer];

textLayer.frame = self.labelView.bounds;

[self.labelView.layer addSublayer:textLayer];

//set text attributes

 

textLayer.foregroundColor = [UIColor blackColor].CGColor;

textLayer.alignmentMode = kCAAlignmentJustified;

textLayer.wrapped = YES;

//choose a font

UIFont *font = [UIFont systemFontOfSize:15];

//set layer font

 

CFStringRef fontName = (__bridge CFStringRef)font.fontName;

CGFontRef fontRef = CGFontCreateWithFontName(fontName);

textLayer.font = fontRef;

textLayer.fontSize = font.pointSize;

CGFontRelease(fontRef);

//choose some text

NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc \

elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ lobortis";

//set layer text

textLayer.string = text; }

 

@end

 

Figure 6.2 A plain text label implemented using CATextLayer

 

If you look at this text closely, you'll see that something is a bit odd; the text is pixelated. That's because it's not being rendered at Retina resolution. Chapter 2 mentioned the contentsScale property, which is used to determine the resolution at which the layer contents are rendered. The contentsScale property always defaults to 1.0 instead of the screen scale factor. If we want Retina-quality text, we have to set the contentsScale of our CATextLayer to match the screen scale using the following line of code:需要设置contentsScale属性
来设为screen scale 因子。

textLayer.contentsScale = [UIScreen mainScreen].scale;

 

This solves the pixelation problem (see Figure 6.3).

The CATextLayer font property is not a UIFont, it's a CFTypeRef.

CATextLayer  font 属性不是一个UIFont,是CFTypeRef。

This allows you to specify the font using either a CGFontRef or a CTFontRef (a Core Text font), depending on your requirements. The font size is also set independently using the fontSize property, because CTFontRef and CGFontRef do not encapsulate the point size like UIFont does. The example shows how to convert from a UIFont to a CGFontRef.

 

Also, the CATextLayer string property is not an NSString as you might expect, but is typed as id.

CATextLayer string属性不是NSString,而是id类型的。

This is to allow you the option of using an NSAttributedString instead of an NSString to specify the text (NSAttributedString is not a subclass of NSString). Attributed strings are the mechanism that iOS uses for rendering styled text. They specify style runs, which are specific ranges of the string to which metadata such as font, color, bold, italic, and so forth are attached.

Rich Text

 

In iOS 6, Apple added direct support for attributed strings to UILabel and to other UIKit text views.

在iOS6上,苹果提供了一个attributed strings 给UILabel 和其他UIKit text views .

This is a handy feature that makes attributed strings much easier to work with, but CATextLayer has supported attributed strings since its introduction in iOS 3.2; so if you still need to support earlier iOS versions with your app, CATextLayer is a great way to add simple rich text labels to your interface without having to deal with the complexity of Core Text or the hassle of using a UIWebView.

Let's modify the example to use an NSAttributedString (see Listing 6.3). On iOS 6 and above we could use the new NSTextAttributeName constants to set up our string

attributes, but because the point of the exercise is to demonstrate that this feature also works on iOS 5 and below, we've used the Core Text equivalents instead. This means that you'll need to add the Core Text framework to your project; otherwise, the compiler won't recognize the attribute constants.

Figure 6.4 shows the result. (Note the red, underlined text.)

Listing 6.3 Implementing a Rich Text Label Using NSAttributedString

 

#import "DrawingView.h"

#import <QuartzCore/QuartzCore.h>

#import <CoreText/CoreText.h>

@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *labelView; @end
@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//create a text layer

 

CATextLayer *textLayer = [CATextLayer layer];

textLayer.frame = self.labelView.bounds;

textLayer.contentsScale = [UIScreen mainScreen].scale;

[self.labelView.layer addSublayer:textLayer];

//set text attributes

textLayer.alignmentMode = kCAAlignmentJustified; textLayer.wrapped = YES;

//choose a font

UIFont *font = [UIFont systemFontOfSize:15];

//choose some text

NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc \ elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ lobortis";

//create attributed string

NSMutableAttributedString *string = nil;
string = [[NSMutableAttributedString alloc] initWithString:text];

//convert UIFont to a CTFont

 

CFStringRef fontName = (__bridge CFStringRef)font.fontName;

CGFloat fontSize = font.pointSize;

CTFontRef fontRef = CTFontCreateWithName(fontName, fontSize, NULL);

//set text attributes

NSDictionary *attribs = @{
(__bridge id)kCTForegroundColorAttributeName:

(__bridge id)[UIColor blackColor].CGColor, (__bridge id)kCTFontAttributeName: (__bridge id)fontRef

 

};

[string setAttributes:attribs range:NSMakeRange(0, [text length])];

attribs = @{

(__bridge id)kCTForegroundColorAttributeName: (__bridge id)[UIColor redColor].CGColor, (__bridge id)kCTUnderlineStyleAttributeName:

@(kCTUnderlineStyleSingle),
(__bridge id)kCTFontAttributeName: (__bridge id)fontRef

};
[string setAttributes:attribs range:NSMakeRange(6, 5)];

//release the CTFont we created earlier

CFRelease(fontRef);

//set layer text

textLayer.string = string; }

 

@end

 

 

Figure 6.4 A rich text label implemented using CATextLayer

Leading and Kerning

 

It's worth mentioning that the leading (line spacing) and kerning (spacing between letters) for text rendered using CATextLayer is not completely identical to that of the string rendering used by UILabel due to the different drawing implementations (Core Text and WebKit, respectively).

leading 行间距
和kerning 两个字符的间距 

 

The extent of the discrepancy varies (depending on the specific font and characters used) and is generally fairly minor, but you should keep this mind if you are trying to exactly match appearance between regular labels and a CATextLayer.

一般差距很小,但是一般情况下很少,但是如果你要注意这事在使用普通的labels和CATextLayer的时候。

A UILabel Replacement

We've established that CATextLayer has performance benefits over UILabel, as well as some additional layout options and support for rich text on iOS 5. But it's fairly cumbersome to use by comparison to a regular label. If we want to make a truly usable replacement for UILabel, we should be able to create our labels in Interface Builder, and they should behave as much as possible like regular views.

 

We could subclass UILabel and override its methods to display the text in a CATextLayer that we've added as a sublayer, but we'd still have the redundant empty backing image created by the presence of UILabel -drawRect: method. And because CALayer doesn't support autoresizing or autolayout, a sublayer wouldn't track the size of the view bounds automatically, so we would need to manually update the sublayer bounds every time the view is resized.

我们可以创建UILabel 的子类并重写它的方法来展示我们添加到为一个sublayer的CATextLayer.

What we really want is a UILabel subclass that actually uses a CATextLayer as its backing layer, then it would automatically resize with the view and there would be no redundant backing image to worry about.

 

As we discussed in Chapter 1, "The Layer Tree," every UIView is backed by an instance of CALayer. That layer is automatically created and managed by the view, so how can we substitute a different layer type? We can't replace the layer once it has been created, but if we subclass UIView, we can override the +layerClass method to return a different layer subclass at creation time. UIView calls the +layerClass method during its initialization, and uses the class it returns to create its backing layer.

但是如果我们继承UIView,我们可以重载+layerClass 方法
返回一个不同的layer 子类在创建的时候。UIView调用layerClass 方法在初始化的时候,使用这个类返回创建的backing layer.

 

Listing 6.4 shows the code for a UILabel subclass called LayerLabel that draws its text using a CATextLayer instead of the using the slower –drawRect: approach that an ordinary UILabel uses. LayerLabel instances can either be created program-matically or via Interface Builder by adding an ordinary label to the view and setting its class to LayerLabel.

 

Listing 6.4 LayerLabel, a UILabel Subclass That Uses CATextLayer

#import "LayerLabel.h"

 

#import <QuartzCore/QuartzCore.h>

@implementation LayerLabel

+ (Class)layerClass {

 

//this makes our label create a CATextLayer

//instead of a regular CALayer for its backing layer

return [CATextLayer class];

 

}

- (CATextLayer *)textLayer {

 

return (CATextLayer *)self.layer;

}

- (void)setUp {

//set defaults from UILabel settings

 

self.text = self.text;

self.textColor = self.textColor;

self.font = self.font;

 

//we should really derive these from the UILabel settings too

//but that's complicated, so for now we'll just hard-code them

[self textLayer].alignmentMode = kCAAlignmentJustified;

 

[self textLayer].wrapped = YES;

[self.layer display];

 

}

  • - (id)initWithFrame:(CGRect)frame {

    //called when creating label programmatically

    if (self = [super initWithFrame:frame]) {

    [self setUp];

  • }

    return self; }

  • - (void)awakeFromNib {

    //called when creating label using Interface Builder

    [self setUp];

  • }
  • - (void)setText:(NSString *)text {

    super.text = text;

    //set layer text

    [self textLayer].string = text; }

  • - (void)setTextColor:(UIColor *)textColor {

    super.textColor = textColor;

    //set layer text color

    [self textLayer].foregroundColor = textColor.CGColor; }

  • - (void)setFont:(UIFont *)font {

    super.font = font;

    //set layer font

    CFStringRef fontName = (__bridge CFStringRef)font.fontName; CGFontRef fontRef = CGFontCreateWithFontName(fontName); [self textLayer].font = fontRef;
    [self textLayer].fontSize = font.pointSize;

 

CGFontRelease(fontRef);

}

@end

If you run the sample code, you'll notice that the text isn't pixelated even though we aren't setting the contentsScale anywhere. Another benefit of implementing CATextLayer as a backing layer is that its contentsScale is automatically set by the view.

In this simple example, we've only implemented a few of the styling and layout properties of UILabel, but with a bit more work we could create a LayerLabel class that supports the full functionality of UILabel and more (you will find several such classes already available as open source projects online).

If you only intend to support iOS 6 and above, a CATextLayer-based label may be of limited use. But in general, using +layerClass to create views backed by different layer types is a clean and reusable way to utilize CALayer subclasses in your apps.

CATransformLayer

When constructing complex objects in 3D, it is convenient to be able to organize the individual elements hierarchically. For example, suppose you were making an arm: You would want the hand to be a child of the wrist, which would be a child of the forearm, which would be a child of the elbow, which would be a child of the upper arm, which would be a child of the shoulder, and so on.

The reason for this is that it allows you to move each section independently. Pivoting the elbow would move the lower arm and hand but not the shoulder. Core Animation layers easily allow for this kind of hierarchical arrangement in 2D, but in 3D it's not possible because each layer flattens its children into a single plane (as explained in Chapter 5, "Transforms").

CATransformLayer solves this problem. A CATransformLayer is unlike a regular CALayer in that it cannot display any content of its own; it exists only to host a transform that can be applied to its sublayers. CATransformLayer does not flatten its sublayers, so it can be used to construct a hierarchical 3D structure, such as our arm example.

Creating an arm programmatically would require rather a lot of code, so we'll demonstrate this with something a bit simpler: In the cube example in Chapter 5, we worked around the layer-flattening problem by rotating the camera instead of the cube by using the sublayerTransform of the containing layer. This is a neat trick, but only works for a single object. If our scene contained two cubes, we would not be able to rotate them independently using this technique.

So, let's try it using a CATransformLayer instead. The first problem to address is that we constructed our cube in Chapter 5 using views rather than standalone layers. We cannot place a view-backing layer inside another layer that is not itself a view-backing layer without messing up the view hierarchy. We could create a new UIView subclass backed by a CATransformLayer (using the +layerClass method), but to keep things simple for our example, let's just re-create the cube using standalone layers instead of views. This means we can't display buttons and labels on our cube faces like we did in Chapter 5, but we don't need to do that right now.

Listing 6.5 contains the code. We position each cube face using the same basic logic we used in Chapter 5. But instead of adding the cube faces directly to the container view's backing layer as we did before, we place them inside a CATransformLayer to create a standalone cube object, and then place two such cubes into our container. We've colored the cube faces randomly so as to make it easier to distinguish them without labels or lighting. Figure 6.5 shows the result.

 

Listing 6.5 Assembling a 3D Layer Hierarchy Using CATransformLayer

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *containerView; @end
@implementation ViewController

- (CALayer *)faceWithTransform:(CATransform3D)transform {

//create cube face layer

CALayer *face = [CALayer layer];
face.frame = CGRectMake(-50, -50, 100, 100);

//apply a random color

 

CGFloat red = (rand() / (double)INT_MAX);

CGFloat green = (rand() / (double)INT_MAX);

CGFloat blue = (rand() / (double)INT_MAX);

face.backgroundColor = [UIColor colorWithRed:red 

green:green blue:blue

 

alpha:1.0].CGColor;

 

//apply the transform and return

face.transform = transform;

 

return face;

}

 

 

- (CALayer *)cubeWithTransform:(CATransform3D)transform {

//create cube layer

CATransformLayer *cube = [CATransformLayer layer];

//add cube face 1

 

CATransform3D ct = CATransform3DMakeTranslation(0, 0, 50);

[cube addSublayer:[self faceWithTransform:ct]];

//add cube face 2

 

ct = CATransform3DMakeTranslation(50, 0, 0);

ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);

[cube addSublayer:[self faceWithTransform:ct]];

//add cube face 3

 

ct = CATransform3DMakeTranslation(0, -50, 0);

ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);

[cube addSublayer:[self faceWithTransform:ct]];

//add cube face 4

 

ct = CATransform3DMakeTranslation(0, 50, 0);

ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);

[cube addSublayer:[self faceWithTransform:ct]];

//add cube face 5

 

ct = CATransform3DMakeTranslation(-50, 0, 0);

ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);

[cube addSublayer:[self faceWithTransform:ct]];

//add cube face 6

 

ct = CATransform3DMakeTranslation(0, 0, -50);

ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);

[cube addSublayer:[self faceWithTransform:ct]];

//center the cube layer within the container

 

CGSize containerSize = self.containerView.bounds.size;

cube.position = CGPointMake(containerSize.width / 2.0,

containerSize.height / 2.0);

//apply the transform and return

cube.transform = transform;

return cube; }

  • - &nbsp;&nbsp;(void)viewDidLoad {

[super viewDidLoad];

//set up the perspective transform

CATransform3D pt = CATransform3DIdentity; pt.m34 = -1.0 / 500.0; self.containerView.layer.sublayerTransform = pt;

//set up the transform for cube 1 and add it

 

CATransform3D c1t = CATransform3DIdentity;

c1t = CATransform3DTranslate(c1t, -100, 0, 0);

CALayer *cube1 = [self cubeWithTransform:c1t];

[self.containerView.layer addSublayer:cube1];

//set up the transform for cube 2 and add it

 

CATransform3D c2t = CATransform3DIdentity;

c2t = CATransform3DTranslate(c2t, 100, 0, 0);

c2t = CATransform3DRotate(c2t, -M_PI_4, 1, 0, 0);

c2t = CATransform3DRotate(c2t, -M_PI_4, 0, 1, 0);

CALayer *cube2 = [self cubeWithTransform:c2t];

[self.containerView.layer addSublayer:cube2];

}

 

@end

 

Figure 6.5 Two cubes with shared perspective but different transforms applied

6 Specialzed layers 特殊层 第一部分 读书笔记的更多相关文章

  1. 6 Specialzed layers 特殊层 第二部分 读书笔记

    CAGradientLayer   CAGradientLayer is used to generate a smooth gradient between two or more colors. ...

  2. 《Ansible自动化运维:技术与佳实践》第一章读书笔记

    Ansible 架构及特点 第一章主要讲的是 Ansible 架构及特点,主要包含以下内容: Ansible 软件 Ansible 架构模式 Ansible 特性 Ansible 软件 Ansible ...

  3. 《CLR.via.C#第三版》第一部分读书笔记(一)

    最近开始仔细研读<CLR.via.C#第三版>这本书.读pdf文档确实很累.建议有条件的朋友还是买书看吧. 我的笔记用来记录我对这本书的理解,简化下逻辑,对每个部分我觉得是要点的进行归纳总 ...

  4. 《从Paxos到Zookeeper:分布式一致性原理与实践》第一章读书笔记

    第一章主要介绍了计算机系统从集中式向分布式系统演变过程中面临的挑战,并简要介绍了ACID.CAP和BASE等经典分布式理论,主要包含以下内容: 集中式的特点 分布式的特点 分布式环境的各种问题 ACI ...

  5. 《Metasploit渗透测试魔鬼训练营》第一章读书笔记

    第1章 魔鬼训练营--初识Metasploit 20135301 1.1 什么是渗透测试 1.1.1 渗透测试的起源与定义 如果大家对军事感兴趣,会知道各国军队每年都会组织一些军事演习来锻炼军队的攻防 ...

  6. 20135320赵瀚青LINUX第一章读书笔记

    第一章-Linux内核简介 Unix的历史 依旧被认为是最强大和最优秀的系统 由一个失败的操作系统Multics中产生 被移植到PDP-11型机中 由其他组织进一步开发 重写了虚拟内存系统,最终官方版 ...

  7. Android深度探索--HAL与驱动开发----第一章读书笔记

    1. Android的系统架构有四层,它的发展目前来说 是比较成熟的,流行于目前的市场.其架构包括四层(linux内核.C/C++代码库.Android SDK API.应用程序). 2. 驱动是直接 ...

  8. Linux第一章读书笔记

    一.Linux历史 Unix强大的根本原因: 1.简洁,仅仅提供几百个系统调用并且有一个非常明确的设计目的 2.文件对待所有东西,通过一套相同的系统调用接口来进行对数据和设备的操作 3.由于用C语言编 ...

  9. 2013337朱荟潼 Linux第一章读书笔记——Linux内核简介

    一.Unix历史 二.Linux足迹 类Linux系统.非商业化产品.用途广泛 三.操作系统和Linux内核简介 1.操作系统 (1)是指在整个最基本功能系统中负责完成最基本功能和系统管理的部分. ( ...

随机推荐

  1. [IT练习册]Python练习项目 思路

    1.爬虫:爬取如下网站一年的内容. http://www.calvarymoravian.org/dailytext 2.蛇形棋: 开发一个类似蛇形棋的游戏.最好基于Web. 3.爬虫+通讯录: 从公 ...

  2. C项目实践之通讯录管理案例

    1.功能需求分析 通讯录管理案例主要实现对联系人的信息进行添加.显示.查找.删除.更新和保存功能.主要功能需求描述如下: (1)系统主控平台: 充许用户选择想要进行的操作,包括添加联系人信息,显示.查 ...

  3. Android系统input按键处理流程(从驱动到framework)【转】

    本文转载自:http://blog.csdn.net/jwq2011/article/details/51234811 (暂时列出提纲,后续添加具体内容) 涉及到的几个文件: 1.out/target ...

  4. 在 Vim 中优雅地查找和替换 vi【转】

    本文转载自:http://harttle.land/2016/08/08/vim-search-in-file.html 总有人问我 Vim 中能不能查找,当然能!而且是超级强的查找! 这篇文章来详细 ...

  5. HDU1260 Tickets —— DP

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1260 Tickets Time Limit: 2000/1000 MS (Java/Oth ...

  6. How to Execute Page_Load() in Page's Base Class?

    https://stackoverflow.com/questions/2737092/how-to-execute-page-load-in-pages-base-class We faced th ...

  7. Powershell 常见问题

    unapproved verbs WARNING: The names of some imported commands from the module 'todo' include unappro ...

  8. lmbench andlmbench 移植测试

    /*********************************************************************** * lmbench andlmbench 移植测试 * ...

  9. 细数vue爬坑之路<坑路大集合>

    坑爹集锦一: npm出现Newline required at end of file but not found错误 原因:eslint语法错误(vue为后缀名的组件结尾没有换行) 解决办法:在结尾 ...

  10. 小程序-demo:小熊の日记

    ylbtech-小程序-demo:小熊の日记 1.CHANGELOG.md # -- * 更新开发者工具至`v0.10.101100` * 修改`new`页的数据绑定方式 & 修改多行文本框输 ...