<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://merpyzf.github.io</id>
    <title>It&apos;s my life</title>
    <updated>2020-09-05T06:48:23.681Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://merpyzf.github.io"/>
    <link rel="self" href="https://merpyzf.github.io/atom.xml"/>
    <subtitle>真正的光芒，需要一点点时间</subtitle>
    <logo>https://merpyzf.github.io/images/avatar.png</logo>
    <icon>https://merpyzf.github.io/favicon.ico</icon>
    <rights>All rights reserved 2020, It&apos;s my life</rights>
    <entry>
        <title type="html"><![CDATA[基于Ionic的混合架构App插件开发指南]]></title>
        <id>https://merpyzf.github.io/post/ji-yu-ionic-de-hun-he-jia-gou-app-cha-jian-kai-fa-zhi-nan/</id>
        <link href="https://merpyzf.github.io/post/ji-yu-ionic-de-hun-he-jia-gou-app-cha-jian-kai-fa-zhi-nan/">
        </link>
        <updated>2020-09-03T03:05:40.000Z</updated>
        <content type="html"><![CDATA[<figure data-type="image" tabindex="1"><img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/timg.jpeg" alt="" loading="lazy"></figure>
<h2 id="开始前准备">开始前准备</h2>
<h3 id="1-所需开发环境">1. 所需开发环境</h3>
<ol>
<li>NodeJs : http://nodejs.cn/</li>
<li>Ionic : https://ionicframework.com/</li>
<li>Cordova : https://cordova.apache.org/</li>
<li>Android : https://developer.android.google.cn/studio/</li>
<li>Plugman : https://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/index.html#validating-a-plugin-using-plugman</li>
<li>Ionic Native : https://github.com/ionic-team/ionic-native</li>
</ol>
<h3 id="2-所需前置技能">2. 所需前置技能</h3>
<ol>
<li>JavaScript 语法基础</li>
<li>TypeScript 语法基础</li>
<li>Java 语法基础</li>
<li>Android SDK 基础用法</li>
</ol>
<h2 id="插件编写开发实践">插件编写开发实践</h2>
<p>以调用 Android 原生 Toast 实现消息提示为例</p>
<h3 id="案例运行效果">案例运行效果：</h3>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/Shell_2020-09-04-19-57-00-475.png" width = "300" />
<h2 id="1-创建插件包">1. 创建插件包</h2>
<h3 id="使用-plugman-cli-创建一个空的插件">使用 Plugman CLI 创建一个空的插件</h3>
<h4 id="a-进入到自己存放插件的目录">a. 进入到自己存放插件的目录</h4>
<h4 id="b-执行如下命令创建插件-添加插件所要支持的平台">b. 执行如下命令创建插件 &amp; 添加插件所要支持的平台</h4>
<p>创建插件</p>
<pre><code>plugman create --name ToastPlugin --plugin_id com.zijin.toastplugin --plugin_version 0.0.1
</code></pre>
<p>为插件添加所要支持的平台</p>
<pre><code>plugman platform add --platform_name android
</code></pre>
<p>执行上述两个命令后将生成如下的结构：</p>
<figure data-type="image" tabindex="2"><img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599105348815.png" alt="" loading="lazy"></figure>
<h3 id="生成插件包中每个文件的作用">生成插件包中每个文件的作用：</h3>
<h4 id="a-pluginxml">a. plugin.xml</h4>
<p>plugin.xml 中定义了插件最后生成平台代码时的文件结构以及针对android平台的一些设置。</p>
<p>一个例子：</p>
<pre><code>&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!-- id：即通过 plugman cli 创建插件包时配置的 pluginID --&gt;
&lt;plugin id=&quot;com.zijin.toastplugin&quot; version=&quot;1.0.0&quot; xmlns=&quot;http://apache.org/cordova/ns/plugins/1.0&quot;
        xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
    &lt;!-- pluginName：即通过 plugman cli 创建插件包时配置的 pluginName --&gt;
    &lt;name&gt;ToastPlugin&lt;/name&gt;
    &lt;!-- ⚠️ js-module 标签用于发布定义插件功能的js文件在web端的调用方式。其中的 clobbers 标签的
    作用用于将 www/ToastPlugin.js 文件中定义的接口发布到 window 对象上，这样 web 端就可以直接通过
     cordova.plugins.ToastPlugin 对象来调用暴露的方法去访问插件的功能。

     ⚠️ 当执行 plugin install 的命令安装插件时 cli 会将 www/ToastPlugin.js 拷贝到 platforms/android/platform_ww/
     plugins/cordova-toast-plugin 目录下。
      --&gt;
    &lt;js-module name=&quot;ToastPlugin&quot; src=&quot;www/ToastPlugin.js&quot;&gt;
        &lt;clobbers target=&quot;cordova.plugins.ToastPlugin&quot;/&gt;
    &lt;/js-module&gt;
    &lt;!--  针对于 Android 平台的配置--&gt;
    &lt;platform name=&quot;android&quot;&gt;
        &lt;!--  该 config-file 标签会将其内部的子标签追加到 platforms/android/app/src/main/res/xml/config.xml 下--&gt;
        &lt;config-file parent=&quot;/*&quot; target=&quot;res/xml/config.xml&quot;&gt;
            &lt;!-- ⚠️ feature 标签下的 name 定义了插件在 ToastPlugin.js 中调用插件的名称 exec(success, error, 'ToastPlugin',
             'coolMethod', [arg0])；⚠️ 注意：第三个参数要此标签的name保持一致，否则在运行时将无法找到插件。
            --&gt;
            &lt;feature name=&quot;ToastPlugin&quot;&gt;
                &lt;!-- param 标签定义 ToastPlugin.java 中 ToastPlugin 类的全路径。用于 Cordova Framework 在运行的时候能够根据类的全路径
                       通过反射机制来实例化ToastPlugin对象。
                       ⚠️ 注意：此处 package 的路径一定要与 source-file 中 target-dir 的属性值保持
                       统一。否则在通过反射进行实例化对象的时候将会出现类找不到的异常。
                       ⚠️ 如果你需要说编写的插件在应用启动的时候就去创建，那么需要再添加 &lt;param name=&quot;onload&quot; value=&quot;true&quot; /&gt;，默认
                       的加载方式为调用插件时采取创建插件。
                       --&gt;
                &lt;param name=&quot;android-package&quot; value=&quot;com.zijin.toastplugin.ToastPlugin&quot;/&gt;
            &lt;/feature&gt;
        &lt;/config-file&gt;
        &lt;!-- ⚠️ 该 config-file 标签会将其内部的子标签最加到 AndroidManifest.xml 文件的根路径下即 manifest 标签下。
            此文件主要用于为Android平台配置权限、声明创建的服务、声明创建的广播、声明创建的活动、设置应用所能兼容的Android系统的版本等。

            关于 AndroidManifest.xml 的用法参考： https://developer.android.com/guide/topics/manifest/manifest-intro?hl=zh-cn
            --&gt;
        &lt;config-file parent=&quot;/*&quot; target=&quot;AndroidManifest.xml&quot;&gt;
            &lt;uses-permission android:name=&quot;android.permission.READ_PHONE_STATE&quot;/&gt;
        &lt;/config-file&gt;
        &lt;!-- ⚠️ 该 source-file 标签主要用于指定插件包中的文件在执行 plugin install 命令后所被拷贝到Android平台项目中的位置。
             ⚠️ 此处拷贝到的路径相对于 platforms/android/app，即 platforms/android/app 为根目录。
        --&gt;
        &lt;source-file src=&quot;src/android/ToastPlugin.java&quot; target-dir=&quot;src/com/zijin/toastplugin/ToastPlugin&quot;/&gt;
    &lt;/platform&gt;
&lt;/plugin&gt;
</code></pre>
<h4 id="b-srcandroidtoastpluginjava">b. src/android/ToastPlugin.java</h4>
<p>ToastPlugin 类继承自 CordovaPlugin ，需要去重写 execute 方法，在此方法中根据 action 响应前端的方法调用，以实现对平台层功能的调用。</p>
<h4 id="c-wwwtoastpluginjs">c. www/ToastPlugin.js</h4>
<p>向 Web 平台暴露插件所拥有的方法，为前端提供屏蔽原生平台（Android/iOS）的插件功能统一方法的调用。</p>
<h3 id="命令参数含义">命令参数含义</h3>
<pre><code>plugman create --name &lt;pluginName&gt; --plugin_id &lt;pluginID&gt; --plugin_version &lt;version&gt; [--path &lt;directory&gt;] 
</code></pre>
<p>👆以上命令各参数含义：</p>
<ol>
<li>pluginName： 插件名称</li>
<li>pluginID： 插件id（即生成ToastPlugin.java的包名）</li>
<li>version：插件的版本描述</li>
<li>directory：一个绝对路径或相对路径，插件将以该路径作为插件的存放目录，缺省以当执行命令的目录来放置插件包</li>
</ol>
<h2 id="2-将空的插件包安装到-ionic-项目">2. 将空的插件包安装到 ionic 项目</h2>
<h3 id="a-编写-wwwtoastpluginjs-定义插件功能方法">a. 编写 www/ToastPlugin.js 定义插件功能方法</h3>
<pre><code>var exec = require('cordova/exec');
/**
 * 
 * @param  msgInfo js 对象，包含 msg 和 showLength 两个属性
 * @param  success js 函数对象，当插件功能调用成功时回调
 * @param  error js 函数对象，当插件功能调用失败时回调
 */
exports.showToast = function (msgInfo, success, error) {
    exec(success, error, 'ToastPlugin', 'showToast', msgInfo);
};
</code></pre>
<p>通过将空的插件包安装到已有的 Ionic 项目能够快速的让我们获得 Cordova Framework 的上下文环境，以此来获得 IDE 代码提示的支持、实现对插件功能的编译运行以进行快速的功能调试。</p>
<h3 id="b-进入到插件包所在的目录使用-npm-init-命令初始化插件包️否则无法执行后续步骤">b. 进入到插件包所在的目录，使用 npm init 命令初始化插件包（⚠️否则无法执行后续步骤）</h3>
<h3 id="c-安装插件到-ionic-项目">c. 安装插件到 ionic 项目</h3>
<pre><code>ionic cordova plugin add ../ToastPlugin
</code></pre>
<p>add 后面为插件包的路径地址，可以是相对路径或绝对路径。</p>
<p>在安装插件时如果 Ionic 项目还没有集成 Cordova 平台，那么在执行安装插件的命令时 Ionic 的 CLI 将会自动为我们集成 Cordova 的环境。</p>
<p>命令执行的运行图如下：</p>
 <img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599118069842.png" width = "600" />
<p>或在安装插件前就通过 <code>ionic integrations enable cordova</code> 命令提前启用 Cordova 环境。</p>
<h3 id="3-编译生成平台代码">3. 编译生成平台代码</h3>
<p>通过执行 <code>ionic cordova platform add android</code>  命令来生成 Android 平台的代码。</p>
 <img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599119545540.png" width = "300" />
<p>⚠️如果权限不足，请使用 超级管理员权限 或 sudo 来执行上述命令。</p>
<p>关于该命令的详细介绍：https://ionicframework.com/docs/cli/commands/cordova-platform</p>
<h3 id="4-使用-androidstudio-导入生成的平台代码">4. 使用 AndroidStudio 导入生成的平台代码</h3>
<h3 id="a-打开-androidstuido-选择-open-an-existing-android-studio-project">a. 打开 AndroidStuido 选择 Open an existing android studio project</h3>
 <img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599121134994.png" width = "600" />
<h3 id="b-选择-platformsandroid-所在的目录执行导入">b. 选择 platforms/android  所在的目录执行导入。</h3>
 <img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599121248417.png" width = "600" />
<p>⚠️ 在mac平台下，点击 open 后，如果出现如下 permission denied 错误提示，请使用 <code>sudo chmod -R 777 platforms/android</code>  为 android 下的所有文件追加权限。</p>
  <img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599121474498.png" width = "600" />
<p>⚠️ 导入后 AndroidStudio 将自动执行 Gradle 脚本来下载项目中依赖的三方库并构建项目，由于国内的网络环境，这里很可能会因为网络连接而导致依赖下载出错，如果出错，请大家开启科学上网工具后再进行构建。</p>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599121706643.png" width = "600" />
<h3 id="c-gradle构建成功">c. Gradle构建成功</h3>
<p>当Gradle完成项目构建后，AS 会以 Android 项目的目录结构进行展示，同时可以看到运行按钮。</p>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599123505691.png" width = "600" />
<p>在开发者选项中开启 Android 系统的调试模式后通过 USB 数据线连接上电脑 AS 即可识别到你的设备，如果手上没有 Android 真机，可以通过使用 AS 提供的模拟器来进行插件开发。</p>
<p>关于模拟器的使用请参考：https://developer.android.com/studio/run/emulator?hl=zh-cn</p>
<h3 id="d-运行项目到设备">d. 运行项目到设备</h3>
<p>点击绿色运行按钮即可将 Ionic 的项目打包成 apk 运行到你连接的设备中。</p>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599124013572.png" width = "300" />
<h3 id="4-开始插件功能开发">4. 开始插件功能开发</h3>
<p>打开 ionic 项目，示例项目的目录结构如下：</p>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599185456217.png" width = "300" />
<p>在 home.page.ts 来调用插件（ToastPlugin.js）向前端暴露出的功能方法，代码如下：</p>
<pre><code>import {Component} from '@angular/core';
// 1. 使用 declare 声明语句来定义 window 的类型，由于 window 是 JavaScript 中的对象，TypeScript中并不存在，为了能够通过编译，必须要进行声明。
declare const window: any;

@Component({
    selector: 'app-home',
    templateUrl: 'home.page.html',
    styleUrls: ['home.page.scss'],
})
export class HomePage {
    constructor() {
    }

    showToast() {
        // 2. 通过 window 对象来调用插件中的方法
        window.cordova.plugins.ToastPlugin.showToast({msg: 'hello, cordova plugin!', showLength: 'short'}, success =&gt; {
            console.log(success);
        }, error =&gt; {
            console.log(error);
        });
    }
}
</code></pre>
<p>此时当在前端点击 打印消息 的按钮时将会触发 Android 层下的 ToastPlugin 的 execute 方法。接下来将在 Android 层编写插件的功能代码。</p>
<p>Cordova 使用 JSON 作为前端到 Android 插件层的消息传递格式。在插件开发中，我们往往需要对复杂格式的JSON数据进行解析，Android SDK 为我们提供了原生的 JSON 解析类，但解析需要手动的去取每一条内容，为了能够快速方便的实现对 JSON 数据的解析，这里我们引入Gson 来帮我们自动完成数据的解析工作。</p>
<p>以引入 Gson 库为例，介绍两种引入三方库的方式：</p>
<ol>
<li>通过向 src/main/libs 目录导入下载的 jar 或 aar 包完成对三方库的引入。</li>
<li>通过 Gradle 完成对三方库的引入。</li>
</ol>
<p>🍭 推荐的方式：尽可能去使用第2种方式来完成对三方库的引入。<br>
原因：由于我们的项目还会去引入别的三方插件，有些时候无可避免的会遇到别的插件引用了和你相同的三方库，如果通过手动下载 jar 包的方式去引入将会出现 jar 包冲突的错误。</p>
<p>下面通过向 app 下的 build.gradle 中的 dependencies 闭包中添加如下内容：</p>
<pre><code>    implementation 'com.google.code.gson:gson:2.6.1'
</code></pre>
<p>修改 build.gradle 文件点击右上角的 sync now 将自动完成对新增依赖的下载。依赖完成后，我们开始在 ToastPlugin.java 编写如下代码：</p>
<pre><code>public class ToastPlugin extends CordovaPlugin {
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals(&quot;showToast&quot;)) {
            Gson gson = new Gson();
            List&lt;MsgInfo&gt; msgInfoList = gson.fromJson(args.toString(), new TypeToken&lt;List&lt;MsgInfo&gt;&gt;() {
            }.getType());
            this.showToast(msgInfoList, callbackContext);
            return true;
        }
        return false;
    }

    private void showToast(List&lt;MsgInfo&gt; msgInfoList, CallbackContext callbackContext) {
        MsgInfo msgInfo = null;
        if (msgInfoList != null &amp;&amp; msgInfoList.size() &gt; 0) {
            msgInfo = msgInfoList.get(0);
        } else {
            callbackContext.error(&quot;参数异常&quot;);
            return;
        }
        if (&quot;short&quot;.equals(msgInfo.getShowLength())) {
            Toast.makeText(cordova.getContext(), msgInfo.getMsg(), Toast.LENGTH_SHORT).show();
            callbackContext.success(&quot;消息提示成功&quot;);
        } else if (&quot;long&quot;.equals(msgInfo.getShowLength())) {
            Toast.makeText(cordova.getContext(), msgInfo.getMsg(), Toast.LENGTH_LONG).show();
            callbackContext.success(&quot;消息提示成功&quot;);
        } else {
            callbackContext.error(&quot;参数异常&quot;);
        }
    }
}
</code></pre>
<h3 id="关于上面的代码需要注意的几个点">关于上面的代码需要注意的几个点：</h3>
<h4 id="a-对于要实现插件功能的类需要继承-cordovaplugin-并重写-execute-方法来处理前端对插件功能的调用">a. 对于要实现插件功能的类需要继承 CordovaPlugin 并重写 execute 方法来处理前端对插件功能的调用。</h4>
<h4 id="b-execute-方法参数及返回值的作用">b. execute 方法参数及返回值的作用。</h4>
<h5 id="execute-方法的三个参数的含义">execute 方法的三个参数的含义：</h5>
<ol>
<li>
<p>String action：action 为前端调用插件的方法名称，在插件开发中我们会根据 action 的值的不同去实现不同的功能。</p>
</li>
<li>
<p>JSONArray args：args 为前端调用插件方法时传递的参数值，是一个 JSONArray 对象。</p>
</li>
<li>
<p>CallbackContext callbackContext：callbackContext 为本次插件方法调用时的回调上下文对象，主要功能是负责处理插件到前端的消息传递。</p>
</li>
</ol>
<h5 id="execute-方法返回值的含义">execute 方法返回值的含义：</h5>
<p>action 的值为前端调用插件功能方法的名称，即对应插件层的具体某一个功能。如果我们有与之匹配的功能实现时我们需要返回 true ，否则返回 false 告知前端调用者这是一个无效的动作。当返回 false 时， Cordova Framework 会给前端返回一个 INVALID_ACTION 的失败消息。当返回 true 时需要我们自己通过 callbackContext 来返回消息。</p>
<h4 id="c-callbackcontext-类的使用">c. CallbackContext 类的使用</h4>
<p>对于是要返回单条还是多条消息需要根据插件实现的功能来判断。假如我们需要编写一个获取设备信息的插件功能，那么只需要返回一条包含设备信息的消息就可以了。如果需要实现电子标签盘点此类的功能，那么插件则就需要不间断的向前端连续传递多条包含电子标签内容的消息。不管是传递单条消息还是多条消息我们都是借助 CallbackContext 类来实现的。</p>
<h5 id="1-传递单条消息">1. 传递单条消息</h5>
<pre><code>      // 调用error方法将会触发前端的error方法回调的执行 
      callbackContext.error(&quot;error message.&quot;); 
      // 调用success方法将会触发前端success方法回调的执行
      callbackContext.success(&quot;success message.&quot;);
</code></pre>
<p>使用上述的消息传递方式，Cordova Framework 是默认只调用一次 callbackContext.error 或 success 后就不会再向前端继续传递消息。</p>
<h5 id="2-连续传递多条消息">2. 连续传递多条消息</h5>
<pre><code> PluginResult pr = new PluginResult(PluginResult.Status.OK, jsonArray.toString());
 // 一定要设置
 pr.setKeepCallback(true);
 callbackContext.sendPluginResult(pr);
</code></pre>
<p>通过以上代码我们可以连续向前端发送多条消息，在创建 PluginResult 对象时我们通过第一个参数设置当前消息的成功或失败的状态，通过第二个参数发送具体的消息内容。</p>
<p>如果插件功能调用后无法立即获取到值，我们可以通过如下代码先向前端传递一个空内容。等获取到实际的值时再调用上面的方法返回具体的值。</p>
<pre><code> PluginResult pr = new PluginResult(PluginResult.Status.NO_RESULT);
 pr.setKeepCallback(true);
 callbackContext.sendPluginResult(pr);
</code></pre>
<h4 id="4-关于耗时任务的处理">4. 关于耗时任务的处理</h4>
<p>我们在插件中编写的代码是运行在 Android 的主线程中的，如果在插件中我们需要做一些比较耗时的操作，比如文件读写、网络请求、音视频格式转换等，我们需要将这些耗时任务的处理逻辑放到子线程中去执行，否则当耗时任务阻塞主线程的时间过长会导致 ANR 的发生。如果任务执行的耗时过长，Cordova Framework 也会给出我们如下提示，提示我们需要将这个任务放到子线程中去执行。</p>
<pre><code>THREAD WARNING: exec() call to ToastPlugin.showToast blocked the main thread for 26ms. Plugin should use CordovaInterface.getThreadPool().
</code></pre>
<p>我们可以直接使用 Cordova Framework 封装好的线程池来启动线程。</p>
<pre><code>       cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                // Perform time-consuming operations
            }
        });
</code></pre>
<p>👹 注意：不能在子线程中做任何和 UI 有关的操作，否则会导致程序崩溃。如果需要更新 UI 请使用Handler 或 getActivity().runOnUiThread() 切换到主线程后再执行与UI相关的操作。</p>
<h4 id="5-处理插件的生命周期事件">5. 处理插件的生命周期事件</h4>
<h5 id="什么是生命周期">什么是生命周期？</h5>
<p>当用户浏览、退出和返回到你的应用时，应用中的 Activity 的实例会在其生命周期的不同状态之间转换，Activity 类会提供许多回调方法，这些回调方法会让 Activity 知晓某个状态已经更改，系统正在创建、停止或恢复某个 Activity，或正在销毁该 Activity 所在的进程。Cordova Framework 会同步 WebView 所属的 Activity 的生命周期的状态到 CordovaPlugin。因此我们可以通过重写 CordovaPlugin 中的生命周期方法来让我们的插件能够响应不同的生命周期事件，以提升应用的稳定性和性能。</p>
<p>下图为 Android 一个 Activity 的生命周期事件：</p>
<figure data-type="image" tabindex="3"><img src="https://developer.android.com/guide/components/images/activity_lifecycle.png?hl=zh-cn" alt="" loading="lazy"></figure>
<h5 id="cordovaplugin-中的生命周期回调方法">CordovaPlugin 中的生命周期回调方法</h5>
<p>在编写插件时，一般我们只需要对下面三个生命周期方法进行处理：</p>
<ol>
<li>onPause：当应用由可见变为不可见时执行该回调，比如我们按home键返回主页时。一般我们需要在这个方法中暂停插件的执行，比如暂停插件对rfid标签的扫描功能。</li>
<li>onResume：当应用由不可见变为可见时会执行该回调，比如我们点击应用图标重新回到应用中时。一般我们需要在这个方法中恢复被暂停的操作，比如恢复插件对rfid标签扫描的功能。</li>
<li>onDestory：当用户退出应用时回调，此时我们需要在该回调方法中执行一些资源释放的操作。</li>
</ol>
<h3 id="5-将开发好的功能抽取为单独的插件包">5. 将开发好的功能抽取为单独的插件包</h3>
<p>这一步比较重要，也是比较容易出错的一步。我们在开发插件功能时需要特别关注在插件开发的过程中添加的源代码文件、资源文件、引入的三方库，因为在抽取为单独的插件包时我们需要将开发这个功能时添加的所有内容拷贝到第一步我们创建的插件包中，并根据 platforms/android 中的目录结构来配置 plugin.xml。</p>
<p>在抽取前我们再来检查下为了实现这个插件功能添加了哪些内容：</p>
<ol>
<li>MsgInfo.java</li>
<li>ToastPlugin.java</li>
<li>通过 Gradle 版本构建工具引入了 Gson</li>
</ol>
<p>第一步：拷贝新增文件到插件包中，我们可以根据源代码的功能来组织文件的存放位置。源代码存放在 src/android 下。</p>
<figure data-type="image" tabindex="4"><img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599207991027.png" alt="" loading="lazy"></figure>
<p>第二步：编写 plugin.xml 文件。</p>
<pre><code>&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;plugin id=&quot;com.zijin.toastplugin&quot; version=&quot;1.0.0&quot; xmlns=&quot;http://apache.org/cordova/ns/plugins/1.0&quot;
        xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
    &lt;name&gt;ToastPlugin&lt;/name&gt;
    &lt;js-module name=&quot;ToastPlugin&quot; src=&quot;www/ToastPlugin.js&quot;&gt;
        &lt;clobbers target=&quot;cordova.plugins.ToastPlugin&quot;/&gt;
    &lt;/js-module&gt;
    &lt;platform name=&quot;android&quot;&gt;
        &lt;config-file parent=&quot;/*&quot; target=&quot;res/xml/config.xml&quot;&gt;
            &lt;feature name=&quot;ToastPlugin&quot;&gt;
                &lt;param name=&quot;android-package&quot; value=&quot;com.zijin.toastplugin.ToastPlugin&quot;/&gt;
            &lt;/feature&gt;
        &lt;/config-file&gt;
        &lt;config-file parent=&quot;/*&quot; target=&quot;AndroidManifest.xml&quot;&gt;
        &lt;/config-file&gt;
        &lt;source-file src=&quot;src/android/main/ToastPlugin.java&quot; target-dir=&quot;src/com/zijin/toastplugin&quot;/&gt;
        &lt;source-file src=&quot;src/android/model/MsgInfo.java&quot; target-dir=&quot;src/com/zijin/toastplugin&quot;/&gt;
        &lt;framework src=&quot;com.google.code.gson:gson:2.6.1&quot; /&gt;
    &lt;/platform&gt;
&lt;/plugin&gt;
</code></pre>
<p>在文章的一开始就已经介绍过关于 plugin.xml 中标签的作用。这里要强调 source-file 标签中 src 属性的值为文件在插件包中的路径，但 target-dir 就一定需要严格按照之前我们在Android 层实现功能的目录结构来添加。</p>
<figure data-type="image" tabindex="5"><img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599208949155.png" alt="" loading="lazy"></figure>
<p>通过使用 framework 标签在 src 属性中填写 Gson 对应的依赖地址来来完成对 Gson 库的引入。</p>
<p>关于 plugin.xml 的详细配置说明请参考：https://cordova.apache.org/docs/en/latest/plugin_ref/spec.html</p>
<p>当我们完成上面的几步配置后，重新安装插件包再运行 app 来测试插件包的抽取是否成功。</p>
<h3 id="6-为我们编写的插件创建-ionic-native-包装">6. 为我们编写的插件创建 Ionic Native 包装</h3>
<p>通过以上五步我们已经完成了一个 Cordova 插件的编写，但基于 Cordova 编写的插件暴露给前端调用的代码是通过 JavaScript 语言编写的（www/ToastPlugin.js），而 Ionic 基于 TypeScript ，为了能够在 Ionic 端实现更容易和统一的功能调用，我们需要通过 Ionic Native 来对已经编写好的 Cordova 插件进行一层包装。Ionic Native 将插件中方法的成功或失败的回调包装在 Promise 或 Observable 中，为所有插件提供通用接口。</p>
<h4 id="编写一个-ionic-native-包装的步骤">编写一个 Ionic Native 包装的步骤：</h4>
<ol>
<li>
<p>从 Github 克隆 ionic-native 项目到本地，后面命令的执行和插件文件模版的生成需要依赖此环境。</p>
<p>地址：https://github.com/ionic-team/ionic-native</p>
</li>
<li>
<p>进入克隆下来的 ionic-native 的根目录</p>
</li>
<li>
<p>创建插件包</p>
<pre><code>// 调用此命令，并将`PluginName`替换为希望添加的插件名称
// 第一个字母一定要大写，使用大驼峰命名
gulp plugin:create -n PluginName
</code></pre>
<p>执行完以上命令将会在src/@ionic-native/plugins目录下创建一个名称为PluginName的插件目录，里面有一个 index.ts 文件，后面 Ionic 插件的编写要基于该文件。</p>
</li>
<li>
<p>开始编写 index.ts 文件</p>
<pre><code>@Plugin({
pluginName: 'ZijinUtilPlugin',
plugin: 'cordova-plugin-x-zijinutil', // npm package name, example: cordova-plugin-camera
pluginRef: 'cordova.plugins.ZijinUtil', // the variable reference to call the plugin, example: navigator.geolocation
platforms: ['Android'] // Array of platforms supported, example: ['Android', 'iOS']
})
@Injectable()
export class ZijinUtilPlugin extends IonicNativePlugin {
}
</code></pre>
<p>这里需要重点指出的是 @Plugin装饰器中每个参数的作用：</p>
<ol>
<li>pluginRef：指的是前端对 Cordova 插件的调用对象，这个值和 Cordova 插件中的 plugin.xml 下的 clobbers 节点的属性值相同。</li>
<li>plugin：值的是 npm 包的名称。</li>
</ol>
</li>
<li>
<p>通过在 ionc native 的根目录调用 npm run build 来进行编译，最后编译生成的 ionic native 包装会生成到 ionic-native/dist/@ionic-native/plugins 目录。</p>
</li>
</ol>
<h4 id="根据上述步骤为-toastplugin-插件创建-ionic-native-包装">根据上述步骤为 ToastPlugin 插件创建 Ionic Native 包装</h4>
<ol>
<li>
<p>通过如下命令创建 ToastPlugin 的 index.ts 文件，在 /src/@ionic-native/plugins/toast-plugin-wrapper/ 下可以找到该文件。</p>
<pre><code> gulp plugin:create -n ToastPluginWrapper 
</code></pre>
</li>
<li>
<p>编写 index.ts 文件</p>
<pre><code>import { Injectable } from '@angular/core';
import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core';
import { Observable } from 'rxjs';
@Plugin({
pluginName: 'ToastPluginWrapper',
plugin: 'cordova-plugin-toast',
pluginRef: 'cordova.plugins.ToastPlugin',
platforms: ['Android']
})
@Injectable()
export class ToastPluginWrapper extends IonicNativePlugin {

@Cordova()
showToast(msgInfo: MsgInfo): Promise&lt;string&gt; {
    return;
}

}

export interface MsgInfo {
msg: string;
showLength: string;
}
</code></pre>
<p>⚠️ 注意 index.ts 文件中声明插件方法的返回值的类型需要根据 Android 层实现的插件功能是要向前端发送一次消息还是多次。</p>
<ol>
<li>
<p>向前端只发送一次消息：使用 Promise 作为插件方法的返回值类型</p>
</li>
<li>
<p>向前端发送多次消息： 使用 Observable 作为插件方法的返回值类型</p>
</li>
</ol>
</li>
<li>
<p>通过在 ionic-native 的根路径下使用<code>npm run build</code> 命令编译源码来生成 ionic 包装文件，生成包装文件的位置 /dist/@ionic-native/plugins/<br>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599217663066.png" alt="" loading="lazy"></p>
</li>
</ol>
<h4 id="可能会遇到到一些坑">👹 可能会遇到到一些坑</h4>
<ol>
<li>
<p>在 ionic-native 下编译生成的类型声明包中的 JavaScript 文件内会对 cordova 进行重复引用：</p>
<p><img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599219722709.png" alt="" loading="lazy"><br>
解决方法：删除多余引入的 cordova 模块</p>
</li>
<li>
<p>在类型声明文件 index.d.ts 中为调用 Native 层功能的方法的返回结果指定为 Observable 不生效：</p>
<p>index.d.ts文件内部方法声明：</p>
<pre><code>@cordova()
openScanReceiver(): Observable&lt;any&gt; {
return;
}
</code></pre>
<p>解决方法：<br>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599219912658.png" alt="" loading="lazy"><br>
给以上截图中的两个index.js补充 {&quot;observable&quot;: true }</p>
</li>
<li>
<p>如果需要为 Cordova 插件写一个 IonicNative 包装时，需要注意将传递的参数写在最前面。</p>
<pre><code>// 🙆🏻‍♂️正确
exports.startService = function (interval, success, error) {
    exec(success, error, 'BackgroundTask', 'startService', [interval]);
};
// 🙅🏻‍♂️错误，Android 层将无法获取传递的参数
exports.startService = function (success, error，interval) {
    exec(success, error, 'BackgroundTask', 'startService', [interval]);
};
</code></pre>
</li>
</ol>
<h3 id="7-在项目中通过-ionic-native-包装调用-cordova-插件功能">7. 在项目中通过 Ionic Native 包装调用 Cordova 插件功能</h3>
<ol>
<li>
<p>首先我们需要将上一步生成的 toast-plugin-wrapper 文件夹拷贝到项目下。</p>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599219056901.png" width = "600" />
</li>
<li>
<p>在 appModule 中的 NgModule 元数据中将该服务提供出去，以允许外部通过依赖注入的方式实例化该插件。</p>
<img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599219176283.png" width = "600" />
</li>
<li>
<p>调用插件的功能。</p>
 <img src="https://blog-1252413502.cos.ap-shanghai.myqcloud.com/1599219523194.png" width = "600" />
</li>
</ol>
<h3 id="结束">🎊结束</h3>
<p>示例代码地址：https://github.com/Merpyzf/PluginPractice</p>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[git pull –rebase 理解]]></title>
        <id>https://merpyzf.github.io/post/git-pull-rebase-li-jie/</id>
        <link href="https://merpyzf.github.io/post/git-pull-rebase-li-jie/">
        </link>
        <updated>2020-07-28T03:04:35.000Z</updated>
        <summary type="html"><![CDATA[<h3 id="这个命令做了以下内容">这个命令做了以下内容：</h3>
<p><img src="https://merpyzf.github.io/post-images/1595905635608.png" alt="" loading="lazy"><br>
a.把你 commit 到本地仓库的内容，取出来放到暂存区(stash)（这时你的工作区是干净的）<br>
b.然后从远端拉取代码到本地，由于工作区是干净的，所以不会有冲突<br>
c.从暂存区把你之前提交的内容取出来，跟拉下来的代码合并</p>
<p>所以 rebase 在拉代码前要确保你本地工作区是干净的，如果你本地修改的内容没完全 commit 或者 stash，就会 rebase 失败。</p>
]]></summary>
        <content type="html"><![CDATA[<h3 id="这个命令做了以下内容">这个命令做了以下内容：</h3>
<p><img src="https://merpyzf.github.io/post-images/1595905635608.png" alt="" loading="lazy"><br>
a.把你 commit 到本地仓库的内容，取出来放到暂存区(stash)（这时你的工作区是干净的）<br>
b.然后从远端拉取代码到本地，由于工作区是干净的，所以不会有冲突<br>
c.从暂存区把你之前提交的内容取出来，跟拉下来的代码合并</p>
<p>所以 rebase 在拉代码前要确保你本地工作区是干净的，如果你本地修改的内容没完全 commit 或者 stash，就会 rebase 失败。</p>
<!-- more -->
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[2014年李志在先锋书店的演讲]]></title>
        <id>https://merpyzf.github.io/post/2014-nian-li-zhi-zai-xian-feng-shu-dian-de-yan-jiang/</id>
        <link href="https://merpyzf.github.io/post/2014-nian-li-zhi-zai-xian-feng-shu-dian-de-yan-jiang/">
        </link>
        <updated>2020-07-24T01:11:35.000Z</updated>
        <content type="html"><![CDATA[<p>这篇文章是2014年李志在先锋书店的演讲，讲述了李志的音乐十年历程。</p>
<h3 id="1-不短暂的艺术生涯">1、不短暂的艺术生涯</h3>
<p>如果说是以前，我可能不会答应这个事情。</p>
<p>正好有两个巧合在里面，一个是前段时间，大概两个星期以前，刚在一个夏令营做了一个类似的活动，他们找了很多人，讲了一些各自喜欢讲的话题，那就趁机再讲一遍吧。</p>
<p>第二个原因就是跟先锋书店有一些渊源，大概在十多年以前疯狂看书的时候，经常去先锋书店，那时候还不在这边，在南大那边的二楼。买了很多书，他们也没给我打折。后来逐渐的对小说之类的书就没有兴趣了，我自己现在也阅读，不过现在是偏向当代史、政治。所以，说实话，这些书对我没什么用了。因为大家也知道，很多书是看不到的，这是闲话。</p>
<p>但是总的来说，在我长期看书的四五年里，先锋书店给我很大帮助，所以他们跟我提这个 想法的时候，我就觉得——那就做一下吧。大概也就是出于这两个原因。</p>
<p>还有一个小原因：我们最近正好在做一些筹划，可能有些人知道我在十年以前出了第一张小样（《被禁忌的游戏》），到现在正好十年，我们做了一个小册子，做这个册子的过程中整理了一些资料，在清理这些东西的同时，我大概的回顾了一下我不短暂的艺术人生，也有一些话想说的。这就是所谓的开场白，这就是我做这个活动的动机。</p>
<h3 id="2-无从模仿的探索之路">2、无从模仿的探索之路</h3>
<p>我一直把音乐分成两块，一块是音乐本身，就是怎么写歌、编曲。一首歌怎么叫好听、怎么叫不好听，这一块我们不谈。因为没什么好谈的——你喜好一个东西是没有道理的。</p>
<p>今天主要讲的是另一块：怎样来做音乐。</p>
<p>就是说，当你有这种想法的时候，如何慢慢的实施，让这个事情如何慢慢地靠近你所谓的理想、幻想。</p>
<p>这是我今天主要讲的话题，也就是所谓的“独立音乐是我的生活方式”。</p>
<p>我不是从一开始就决定了现在所有做事情的方式和方法，这是在长期的过程中，摸着石头过河，失败、总结、思考，这样一路慢慢过来的。没有一条清晰的、特别明确的方法。</p>
<p>那么为什么会一不小心做了十年直到现在？有两个原因是很重要的。</p>
<p>第一个就是，我找不到一个可以模仿的人，他们是怎么来操作他们的音乐的，不管国内还是国外，可能会有，但我没发现。</p>
<p>第二个是，我们所看到的传统音乐，或者说非主流音乐，他们那些做法我很讨厌——虚伪做作、不勤奋。所以一方面你对他们的做法不喜欢，另一方面你有没有一个人可以去模仿，座椅只能硬着头皮，按照自己的想法来。但是我的能力和我的经历都是有限的，所以这条路走到现在，还是挺波澜壮阔的，只不过大部分观众没有看到。</p>
<p>这也导致我现在不是一个人在做事情，我后面有一个很大的团队，是我挑选过来、拉过来的，我们有共同的价值观。</p>
<h3 id="3-从退学开始说起">3、从退学开始说起</h3>
<p>先讲一下大概在十年前的事情，我在2004年开始做的第一张小样，那时候我已经26岁了，也就是说现在我36岁，在26岁之前，我是一个按部就班的生活着的人，出生在农村，村子里最普通的家庭，自己念书。</p>
<p>也没有告诉你该怎样生活，也没有人告诉你世界是怎么样的，因为我的父母基本上都是文盲。包括我的所有亲戚，加起来一两百个人都在老家，过着农民或者打工的生活。</p>
<p>我是他们当中唯一一个受过高等教育的，虽然没有受完。也是唯一一个没有把高等教育当回事的人。一个人生活在外面，他们还在农村，所以一直到现在我都没有跟我的家人包括父母、和我的朋友说我在做什么事情，我跟他们说我在上班。</p>
<p>直到1997年高考我到南京来上大学，这前面的十几年一直是在农村，顶多是去县城。前段时间，大概一个星期以前，我刚和我高中的班主任吃了个饭，当然还有我几个同学。我们都没有想到每个人的路可以走得那么千奇百怪，尤其是我，居然从事了这么一个职业。</p>
<p>因为在大部分人看来，从事所谓的艺术行业，要么需要家庭背景，要么相当有天分，要么你很有钱，但是我什么都没有。</p>
<p>很难难想象像我这样的一个人从事这样一个行业，没有受过任何的音乐教育，也没有受过任何的文学教育，因为我念的是理科。在我上大学之前都没有读过课外书，语文永远是不及格。（这样一个人居然能考上东南大学= =）所以后来很多人说喜欢我写的歌词我自己都觉得不可思议。</p>
<p>这不正是不按套路出牌，所以显得有点不一样？但是我对自己的认知一直是在音乐上天赋很平凡的一个人，我就是这么真实的认为的。</p>
<p>上了大学的，99年来到南京，上了两年我就从学校出来了，当时从学校出来并没有想得很清楚去干什么，只不过是不喜欢那种教育方式，不喜欢学校的各种糟糕的东西。</p>
<p>1999年我从学校出来的时候，带着两个想法，一个是音乐的，一个是文字的。我对这两块比较有兴趣，但是我很清楚我对这两块并没有天赋，所以又有很长一段时间，我不知道我应该把精力放在写作上，还是放在音乐上，迷茫了很长一段时间。后来我决定还是尽量偏向音乐这一块，当然这两块并不冲突。现在我一直在写东西，有些还会在往上贴一下，有些自己看看就扔掉了，尤其在没有网络和电脑的时候都是手写，那些写得好的手稿都扔了。</p>
<p>我一直有这样两个想法，偏向音乐只是有一天，我突然觉得我现在的心情让我用文字描述特别难，可你要给我一把琴，我一嗓子，啊，蛮爽的，就这样。所以才会偏向于这个。</p>
<h3 id="4-迷茫未必是坏事">4、迷茫未必是坏事</h3>
<p>从99年到04年有五年的时间，过的是非常普通也很艰苦的生活，因为没有生活来源，我家里也不可能给我钱，我从学校出来就再也没跟他们要过钱，我也没有认真地去找个工作。</p>
<p>可能是这边叫两个学生，那边酒吧唱两天，混吧混的状态，但是那五年对我后来的帮助很大，因为我有大把的时间，除了茫然和迷茫之外，我有大把的时间去阅读跟思考，包括听大量的音乐，所以那段时间是挺重要的。</p>
<p>那段时间我写了可能有四五十首歌，都是后来发表了的，还有很大一部分都忘掉了或者是我觉得不好就扔掉了，因为我不会记谱也没有录音设备，所以那五年对我来说特别重要。</p>
<p>所以经常有人在网上问我，他现在很迷茫很痛苦，没有工作什么什么的……其实在我看来，这正是一个好的事情——如果你过几年回头来看的话……</p>
<h3 id="5-给自己一个交代吧">5、给自己一个交代吧</h3>
<p>OK！这个节奏有点慢不好意思！</p>
<p>2004年，我在夏天的时候去了一趟银川。也是机缘巧合，我的一个大学同学在那里工作。他带我去了西夏王陵，就是西夏王朝的一些皇帝的陵墓，在戈壁滩上。</p>
<p>中午很热，我们几个人走过去，远远地看到李元昊的陵墓在那里，孤零零的一个小土丘。</p>
<p>当时我很感慨，我觉得：操！李元昊老师文公武略雄霸一方，死了之后怎么样呢？就是这个小土丘。有多少人知道李元昊的？同样姓李大家都知道李白，李白出生在哪里？死在哪里？</p>
<p>也没几个人在乎。所以我才想到十几年前的一句广告词叫做“土木只是外表，通性才是世界的经脉”所以我就想物质都是外表，精神才是整个人类的经脉。我就想哪个时候我死了，我留下什么呢？我什么都没留下，我一拍大腿，就决定回去把我以前写的那些歌录一下。录得目的不是要展示给大家看、要怎么样，只是对我自己一个交代，记录一下。</p>
<p>因为我没有录音的设备，我没有录音机也不会记谱，所以就散落在各种纸张上面，还有我自己的脑子里面。我就想，把这东西录一下吧。</p>
<p>于是就开始了第一次的录音。当时条件艰苦是必然的，因为什么都没有，我跟我一个朋友在白下路的一个地方在录，那个地方是他上班的公司，有一个简单的电脑，我们借了个声卡，借了些琴，两个人完成了所有的东西，那是2004年。</p>
<p>录完之后花了不少钱，对我而言是一笔巨款——5000元钱。觉得去卖卖吧！肯定有人买的，就去珠江路刻了250张还是300张的，20块钱一张放在各种小书店音响店卖，做完第一张就做第二张（注：《梵高先生》），因为那个时候有大量的歌等着我去录，在我桌子前脑子里，一录就录了三张（注：第三张为《这个世界会好吗》）。</p>
<p>前三张的动机都是一样的，就是记录。赶快把自己的东西拿出来，防止自己突然死亡或者忘了，那么对我而言这一生就活得毫无意义——因为我没有做过什么贡献，我只有把自己记录下来。所以那些东西都做得很糟糕或者很劣质是必然的。</p>
<p>第一、我的目的就是记录。<br>
第二、我没有能力，编曲的能力、做唱片的能力，挣钱的能力、关系的能力。比如说你肯定有喜欢的吉他手，但是你没有能力把他请过来帮你录，就是这样。</p>
<p>这种事情是很必然的，没有办法，我现在自己都不敢回头听这些东西，确实很劣质。但是怎么办呢。</p>
<h3 id="6-始终离不开钱">6、始终离不开“钱”</h3>
<p>刚刚做完之后，我就意识到另一个问题，现在钱花得越来越多，因为录唱片还是挺花钱的，当你经过一次录音、两次录音之后，有信心把它做得好些，当你要去实现这个想法的时候，很大部分要靠你的钱。</p>
<p>你这个人再有魅力、再厉害、名望再大，当你做到一定份上想把事情做大，还是需要钱去开路。<br>
因为所有的人，至少在这个行业里的人不是衣食无忧的，大部分人活得还是比较艰苦的，大部分的人靠这个生活，需要有一定的回报。</p>
<p>所以做了三张碟，花了三年时间，欠了五六万各种各样的借款，这个时候正好有个机会，去成都上了两年班，当时的目的也很简单，上班、挣钱，把账还了。</p>
<p>但实际上现在我发现，那两年对我又特别重要，这所有的“重要的感觉”都是事后发现的。</p>
<p>固为在成都的两年，我就是个上班族，早上起来上班，下午回家，没有交际没有朋友，没有任何东西。就是上班、回家、上班、回家。回家干嘛呢。回家就是看看电视剧，看看书，弹弹琴。特别清净的一段时间，我从成都离开的时候，我看了下手机，认识的有电话号码的成都人，也就五个，而且这五个里还有四个是小酒馆的。</p>
<p>所以那段时间特别清淡，写了很多歌，那段时间写了有两张唱片的量，于是我才能在回来之后的三年又做了三张碟。这三张里的好多歌都是在那个时候写的。所以，这都是机缘巧合。</p>
<p>做到第四张（《我爱南京》）的时候是难度最大的，因为那个时候我已经意识到一张糟糕的唱片对自己有多么坏的影响，我就想做一张至少在听觉上正常、有行业标准的唱片，我还记得我花了很大的力气跟乐队说：“我们定要做张最牛逼的。”</p>
<p>当然这个是吹牛B的话，在那个时候确实是绷着一股劲，我得证明自己能把东西做好，而且从当时看，各方面条件都已经很成熟了——首先我借了三十万，这个钱足够去做个唱片了，其次我当时有南京最好的乐手，圈内也有些朋友在帮我的忙，比如老狼。</p>
<p>所以说有点踌躇满志地去做。但是过程很痛苦，这张唱片花了我六个月以上的时间，而且是高强度的工作，大家知道做双张（《我爱南京》分为两张碟，其中第一张是李志原创的歌曲，第二张是李志翻唱别人的歌曲）的时候一张在南京录。</p>
<p>一张在北京录，那时候高铁还没开通，我就是两头跑，涉及四五十人，经常上午从南京飞到北京，事情办完了坐最后趟航班飞回来，不计成本和代价地周转，那也是我历史上最瘦的时候。</p>
<p>确确是劳动量过大了，我现在160斤，那时候130不到。所以那是非常累的。现在看来那样做是值得的，花了很多钱，三十万全部花完了。虽然它只是我一个稍微像样一点，有出版号，音质不那么劣质，唱片里面没什么杂音的东西，对我来说还是有收获的。</p>
<h3 id="7-你知道完美的定义吗">7、你知道“完美”的定义吗？</h3>
<p>做到第五张（《你好，郑州》）就已经很顺其自然了，换了一个录音棚，换了一个录音师，换了设计师，感觉一切都顺风顺水、顺其自然。</p>
<p>第六张更夸张一些，第六张就是前段时间京东发售的《f》，是我最大胆的一次，我不告诉他们乐手我想要什么，我让他们去想。所以乐队每首歌都做了四五个版本，让我挑一个，而不是我告诉他们想把歌做成什么样。</p>
<p>这种想法很大胆，有些听众也会听出了第六张和之前的差异特别大，因为那全是乐队的想法，我挑的一种，可能是我喜欢的，也有可能是考虑到整个唱片的连贯性。</p>
<p>出了第六张之后就是2011年。12和13这两年就没有出唱片。干了什么呢？我待会再讲，总结下第一个部分，就是我做唱片的过程，很多听众一直会问我：“逼哥我想录一个东西，我发现困难很大该怎么办？”遇到这种问题我真是不知道该怎么回答，因为我早就发现一个事情做好了和做完了是永远矛盾的，尤其是在所谓的艺术领域里。</p>
<p>你必须要选择一个，是做好还是做完，我选择做完。</p>
<p>因为在我看来，首先，做好是没有个标准的，其次，很多人打着做好的旗号在偷懒，我作为个工科生，喜欢做个了断，把个事情做完。</p>
<p>我知道它很劣质，知道它很糟糕，但是我把它做完了。把它做完了，0K我去做下个事情。就算它很糟糕，我还有机会去重做，但你一直为了做好往下做，那是个无穷止境的东西。</p>
<p>有很多同行做个唱片，可以录四五年再混音四五年，所谓的“磨”，当然可能做出精品来，但我不喜欢把我的精力放在那个里面去。唱片的部分大概是这个样子，下面是做演出。</p>
<h3 id="8">8、</h3>
<p>片的部分大概是这个样子，下面是做演出。第四张唱片花了三十万，当时是很有信心把这个钱赚回来的。实际上后来销量非常惨淡，我自己内心肯定不服气，我觉得做的还不错呀。</p>
<p>为什么就没人买单呢？<br>
那个时候的自己很狭隘，现在觉得挺正常的，因为所有人的唱片都卖不动，在座有多少人是没买唱片的？我自己也很少买。所以唱片本身不能带来经受益的话。</p>
<p>作为个音乐人该如何去生活呢？你至少要吃饭呀。你要买琴、添设备，能想到的只有做演出。做演出是来钱最快的一种方式，我们最近几年保持在平均每年四十场演出，各种娄型的。但刚开始的时候并没有演出，甚至完全没有演出的机会。很多人说很喜欢我现在的演出：你们做得很职业很专业。但实际上这些东西都是在十年的过程中不停地摸索、学习同行，不停地看DVD，不停地实地考察、思考，然后过来的，并不是开始就想好，并不是开始就知道怎么做的。</p>
<p>这个过程是个很长期的学习过程。</p>
<p>我记得我自己做的第一场演出是05年的年底，在前面那个半坡村咖啡馆，当时我刚把第二张录好，然后做个简单的首发。那个时候对演出的概念就是贴个海报，跟朋友打个招呼，然后借几个音箱，然后就开始吧，就这样子，根本没有什么演出的节奏、主体、结构，什么都没有。因为完全不知道该怎么做，慢慢的发现，演出是能够赚钱的，但是要想持久地靠演出赚钱，必须要保证演出的质量。</p>
<p>我想各位经常看清出定会有体会，一旦看完某个人的演出，就觉得，哎呀我以后不想看了，不是他的音乐不好，而是他的演出乱七八糟的，我个人会这样想。</p>
<p>但好的演出你看完了，不管音乐喜不喜欢，你会觉得下次我可以再来看看，因为现场演出音乐本身的发挥是很难把控的，但是音乐之外的东西，比如你的次序，你是不是准时，你的声音是不是好，声音从物理上说是不是好，是可以把控的，所以在我看来主流音乐和非主流音乐有个很大的区别在于这一块，那就是主流音乐会保证音乐之外的东西在个行业的标准线之上，但非主流音乐完全没有。</p>
<p>演得好的时候会特别舒服，演得差的时候就是一坨屎。那么在非主流音乐这一块，所谓的大牌乐队，跟小众乐队的区别也是在于大牌乐队他会有个基准线，他哪怕今天情绪不高，哪怕失恋了或者父母死了，你完全听不出来。因为他的其他指数是有行业标准的，至少你听不到啸叫，你会听清楚人声。</p>
<p>我经常打的个比方就是，假如周杰伦在奥体开了场演出，涅槃在个livehouse开一场演出，让哟个完全没有听过音乐的老母亲去两个地方听，她肯定会喜欢周杰伦那种，为什么。</p>
<p>因为在物理上，她的耳朵是舒服的。但是你在小地方，再好的音乐她耳朵也难受，当她没有音乐审美的时候她的耳朵是难受的，她在生理上是难受的，自然会对另一个有好感。</p>
<h3 id="9-口碑建立在高昂的成本">9、口碑建立在高昂的成本</h3>
<p>所以在意识到自己的问题之后我就直在想，怎样把现场的声音做好。</p>
<p>我不管这个歌唱的怎么样：唱功怎么样、乐队能力怎么样，我先把声音做好，这是我的思路，所以我才会从逐渐的乱七八糟办演出，到自己租赁设备，而且都是按照自己想要的设备开个设备清单去租赁，花很大的成本来做这个事情，而且这些设备好多南京都没有，都是从外地过来的。</p>
<p>这样的做法开始不只是观众不理解，包括我们团队我们乐队都不理解，他们觉得完全没有必要，但是我脑子里面很清楚，我觉得声音要有最基本的保证，这种保证的第一因素是硬件设备，其次才是乐队的能力包括歌手的能力。</p>
<p>所以一直到现在也是这样，我们决定去哪个地方演出不清出，第一个指标就是这个地方的设备够不够，为了减少麻烦或者说保证一定的状态，大部分的演出我们都自己带设备。</p>
<p>在去年的上半年我们做了个《春末的南方城市》的巡演，当时我们带了一卡车的设备，一卡车的概念就是到了一个地方，只要你给我一个电源，我就能演，不只是乐器音响，连乐谱架、话筒架，甚至是接线板我都带了。</p>
<p>这样看起来非常潇洒，但成本也是非常大的，风险也非常大。所谓成本大是肯定的嘛，这么多设备的租赁、搬运，还要有工作人员。</p>
<p>所以我们去年巡演最多的时候整个团队25个人，一半人在天上飞，另一半人开着车带着设备在地上跑。这是我做过最大胆的一个尝试。还有个风险就是，到了一个地方要先把设备撤完，再把设备安装上去，这个工作量是很大的，这不是说到了一个地方音箱一接就可以，这种工作量之大会导致所有人高度紧张，同时我又要求必须准时开场，他们每个人都绷得非常紧，但是所有的这些，所谓的风险也好、成本也好带来两个好处。</p>
<p>第一个好处是我可以得到足够的休息，然后保证最好的体能去唱歌。</p>
<p>我们在去年巡演到最后的时候我可以在演出开始前五分钟到后场，一个场地我从来没来过，我可以在房间睡觉，睡到演出开始前到这里，我拿起琴就可以演，因为所有的工作人员把所有事情都做完了，连调音全部都调完了，他们把琴往我身上一放，123开始。</p>
<p>足够的休息才有足够的体能去演，所有我们的演出一般都在两个小时以上，我觉得国内没有多少人可以做到这么长时间的演出，当然前提是要休息好。</p>
<p>这是第一。第二，好处在于我们的声音有做足够的保证，因为所有的设备自己都很熟悉很清楚，知道该怎么调。</p>
<p>如果在这个城市演用这套设备，在那个城市演用那套设备，每个城市的配置都不样，什么事情都要从头来遍。去年巡演做到最后的时候，最后一场我们摆好设备之后开始调音的时间都不超过20分钟，非常快！这是巡演的事情。</p>
<p>OK！巡演存在一个动机，对我而言大部分巡演的动机都是赚钱，因为其他没有来钱的方式，只有这个是赚钱的。</p>
<p>另外一个就是锻炼队伍。这个锻炼的队伍的不只是乐队，也包括团队，也包括配合的舞台助理、检票、售票的锻炼。</p>
<p>到目前为止我大概做了四五次巡演把，虽说中国市场很大，真正能够赚钱的城市还是数的过来的，那么我就会思考以个问题，如何让一个人看完你的演出之后还想再来看。</p>
<p>这个行业、圈子很小，看演出的人就那么多，很多人看了一次之后下次就不会再看这个人的演出。<br>
所以我一直在担心，怎么样让大家持续地看演出，我们做过个调查，问：你为什么来看我的演出。其中有一个原因是这么说的：其实你的歌我都听过了，你的演出我也看了好多次，我对演出本身没有任何兴趣，但是我过来可以见到很多认识的朋友，虽然不是选的人最多的，但当时我还是挺震惊，但想想也是可以理解的，就是演出逐渐地会变成一种社交，这也是现在音乐节的一个趋势。<br>
现在不再是音乐，而是大家的一个活动场所、一个PARTY，那么你怎么样让这些来参加社交活动的人感到愉快呢？</p>
<p>这又是另一个非常令人头疼的问题。</p>
<h3 id="10-赔钱也要做跨年演出">10、赔钱也要做跨年演出</h3>
<p>OK。说下跨年，大家知道我现在在南京做了四年的跨年，第一次做的时候是很偶然的，当时我还在乌鲁木齐演出，当时我的赞助人，一个艺术基金（注：汤臣艺术基金）建议我做这个演出。</p>
<p>但是第一、我的乐队当时处于不成熟的状态，第二、我还在外地没有时间回来策划操盘，才会想了把朋友拉过来每个人演半个小时。</p>
<p>做完第一次跨年，其实效果并不好，虽然虽然在场的观众还是挺囊的，因为当时从八点直演到凌晨三四点，场有着九组艺人超长时间的演出。从那次之后那九个人再也没有一起出现过，同时出现三四个都比较少，因为大家越来越忙了，周云蓬、万晓利、苏阳、小河、马条、张玮玮、郭龙、我还有欢庆（注：李志按人头数确实是九个，但当时演出的还有吴吞，李志把张玮玮和郭龙这组艺人数成两个人，就没有然后了）而且这场演出一直到开始的时候都有票没有卖完，实际上票价并不高。<br>
而且那场演出他们这八个人包括我自己收的费用是非常非常低的，我都不好意思说出来，怕会影响他们现在的报价（听众大笑），因为这是作为给我的个面子，才来南京演出一场。</p>
<p>尽管如此，这场演出的亏损是20万，那是2010年。第一次做是这样一个亏损的状态。而且除了当时在场人之外，外面并没有多大的反响。然后这就奠定了跨年的基调，就是亏钱。做了四年，我算了下，亏损大概在120万左右，这个120万有80万是我自己活生生地亏出去的，有40万是赞助过来的。<br>
所以对我自己而言，我四年时间要活生生地多赚出80万来填补这个空洞，所以我才会那么频繁地去做巡演，所以才会音乐节报价那么高，导致别人不敢找我。</p>
<p>这都是一条线上的，就是跨年的亏损只是我长期亏损的一部分，但是赚钱的唯一途径就是巡演，而且还要小心冀冀地控制巡演。</p>
<p>比如说上半年那个大胆的巡演，最后的利润可能在15万，但那15万是建立在很多前提之上的，也就是说很有可能是不赚钱甚至亏钱的。</p>
<p>那么赚钱赚在哪边呢。这是由于我们的票务系统，这次使用了一个新的票务，把这个成本省了下来。</p>
<p>所以会去年的下半年开始做“杀鸡取卵”，今年上半年做叫什么我也不记得了，各种巡演。因为到了夏天就要考虑，今年跨年怎么办、今年跨年找谁、会亏多少钱、要去做预算。如果身上没有那个钱，就没有底气去做这个事情，这也是我一贯的做事方式。</p>
<p>我会跟很多人借钱，但是涉及到工作，我没有欠过谁的钱。比如说我们跨年会涉及到十几个合作方，我没有欠过谁的钱。而且绝大部分都是在演出前把钱全部结完。像我们乐队,一般来说会在最后一次排练就把钱结完，不用等到演出结束之后。</p>
<p>所以你会需要有一个所谓的前期资金，这个前期资金就是你对整个演出的预算是多少，不用去考虑票房，如果演出预算是五十万，那么你先要把五十万拿到手上，我才会去做这个事情。</p>
<p>而不是说我准备十万，期待有四十万的票房，这样做的风险会特别大，所以说好多的音乐节、演出会流产就这个原因，它的资金链是不稳固的，总是把期望放在票房上，但是票房是最不可靠的东西。</p>
<p>谁知道呢。可能明天我的演出就没有人来看了。</p>
<h3 id="11-南京南京">11、南京！南京！</h3>
<p>现在还是再说跨年，无数的听众包括我们团队的人有一个问题他们不理解，那就是，为什么你的跨年要放在南京。</p>
<p>因为从条件上讲，好多城市比南京要好非常非常多，就说北京、上海吧，第一、有大的场地，南京找不到大的场地，这个问题我不跟你们讨论，因为我懒得说了。人家问我为什么选这个场地不选那个大场地，每次都是一票难求，但是没有票卖，因为没有大场地，为什么找不到大场地？这我就不提了。</p>
<p>很多人不理解的是，为什么你非要把跨年放在南京。你自己亏钱又那么累，还被观众骂 因为买不到票嘛。办这样一个演出，目的是什么?</p>
<p>OK，我可以告诉大家，我的想法很简单：我希望，未来有越来越多的二三线城市的音乐爱好者能在自己的城市从事音乐工作，不是跑到北京。</p>
<p>如果每一个城市都有一个像我这样的人，吹牛逼点哦像我这样的人，坚持在当地，选当地的乐手，在当地做音乐，十国的非主流音乐不会这个样子。</p>
<p>不是所有的人，不是所有人喜欢音乐，然后搞乐队，然后跑北京，然后过几天回来。</p>
<p>当今这种情况也没有任何的发展。但实际上，每个地方都有很多天才的人，包括南京也是，只不过你不知道。有各种原因导致他无法继续从事音乐行业。</p>
<p>那么我一直希望，或者说幻想我的所作所为能够让一些人看到希望，什么希望呢？</p>
<p>就是在南京也是可以做乐队的，也是可以通过做乐队生活得不错的，在成都也可以，在西安也可以，在广州也可以，不定非要跑到那个地方去（注：指北京）。我们看西方，纽约有一帮人做音乐，西雅图有，洛杉矶有，各个地方都有，但中国呢？除了北京你能数出几个。</p>
<p>石家庄有个万青（万能青年旅店），成都有一个声音玩具，上海有一个顶马（顶楼马戏团），南京有一个李志，还有吗？</p>
<p>没了。当然这个问题说起来就很复杂了，这是因为资源分配的不公平、不均匀，不只是在这个行业这样子的。</p>
<p>我在做完两次跨年之后，那时候遇到了很多困难。</p>
<p>有一天我去南京家琴行找个朋友，然后看到两个小孩在练琴，我在他们后面他们没有看到我，练了一会儿个人对另一个说：“你觉得我这样能够给李志弹琴吗？”</p>
<p>当时我特别感慨，我希望的就是大家能通过搞这个所谓的非主流音乐能够看到希望、能够赚到钱，能够生活得好起来。</p>
<p>只有这样，才会有越来越多的人从事这个行业，只有越来越多的人从事这个行业，这个行业才会越来越好，因为目前为止，这个行业里面的从业人员不管是在舞台前面还是在舞台后面，大部分还是傻逼，没文化没素质，什么都没的。</p>
<p>他们是走投无路才来做这个行业。如果说不让他们唱歌，他们可能连一个农民工都做不好。你可以算下，这些人里面，有几个受过高等教育。他们以为看几本文艺小说、看几部电影、听几张碟、摆个POSE、穿个衣服这就是摇滚乐吗。</p>
<p>不是。摇滚乐在我看来从不是个高尚或者下贱的东西，在我看来这是一个很普通的行业。</p>
<h3 id="12-做音乐前要想清楚解决钱的问题">12、做音乐前要想清楚解决钱的问题</h3>
<p>任何一个行业他都需要一些牛逼的人、聪明的人、天才的人、有责任感的人、有素质的人进来之后，才能够把它做得更好。</p>
<p>所有能吸引人进来的不只是它本身行业的魅力，一个重要原因就是物质，要有钱。</p>
<p>崔健在很多年前就说过，中国摇滚乐什么现状？<br>
羊毛出在牛身上。</p>
<p>他本身是没有钱的，就是忽悠一个傻逼过来投点钱、忽悠一个傻逼过来投点钱，它本身转不起来。<br>
所以我为什么一直想纯粹地做这个事情，我就想通过唱片、通过演出，通过我的数字音乐的销售来赚钱，能够把团队运营下去，让自己生活得很好。我就想，不要那些傻逼，我们能够转起来，我一直是这个想法。</p>
<p>所以跨年的目的就是，包括我，乐队成员也是南京的，他们都在南京生活。</p>
<p>实际上我认识很多很牛逼的乐手，我也有很多机会去重新换个地方去找一帮人来做。但我还是坚持在这边弄，就是刚才讲的那个小故事，那个不是笑话，而是我希望……OK，有人不要像我们那个年代，我的很多朋友，90年代和我起做乐队的，因为生活的原因，他在这个行业里面没法吃饭，所以转行了。我不希望这样的情况越来越少……</p>
<p>我希望这样的情况越来越少。我希望更多的人他爱好这个东西，然后投入这个行业，能够赚到钱，能够生活得很好。能够在他的父母面前，他的所有亲戚朋友面前能够所谓很正常地从事摇滚乐——我没什么，就跟我去写字楼上班一样。</p>
<p>在九十年代的时候，在我们早期做乐队的时候，我很多朋友都是才华横溢的，现在没有一个人是在闯新路。南京有个很好的乐队叫续弦（注：续弦乐队是南京最棒的GRUNGE乐队），他们那几个人非常有才华，但怎么办呀。他做不下去他没法赚钱呀。他能怎么办？</p>
<p>所以我一直说我的运气很好，因为我没有才华，但是我很早就认识到这些问题，我在努力地解决钱的问题，我很早就提出了所谓“排练费”这种东西、排练迟到要扣钱这种东西，把我从事通信行业里面那种项目管理的思路带进来在做很多事情。</p>
<p>我把他当一件工作，一个简单的行业，它不高尚也不下贱。所以，如果在座的，有音乐爱好者的话，我建议你勇敢地走进来，但是我建议你在勇敢地走进来之前。也要想清楚了，你可能做不到我这么赚钱。但是我还希望更多人能够进来，我特别反感所谓的同行相轻的思想，总希望别人跌倒，显得自己就牛逼的想法。其实这种想法在这个圈子里面很普遍。</p>
<h3 id="13-要是中国有十个万青">13、要是中国有十个万青</h3>
<p>我希望能够有越来越多的人进来，如果说——我经常讲这句话：如果中国一年出十个万青，早就不是这个样子了，音乐节早就不会这么难看了，早就不会是那帮老傻逼唱着一成不变的歌、一成不变的编曲、一成不变的发型、一成不变的台词在那边骗那些傻逼们。</p>
<p>没有新人能进来，上不了台面啊。永远是那帮人他可以吃一辈子。</p>
<p>当然现在情况已经好转了。</p>
<p>还是回到刚才那个话题，唱片不赚钱，演出能赚钱，演出风险还特别大。而且为了把这个钱赚得很有底气，需要付出很大的劳动。比如说去年我们的不插电巡演是三个人，今年我们变成四个人，你别看台上多了一个人，实际上工作量增大了很多。那么也就是投入会很大，那么为什么要这样子变呢？</p>
<p>要考虑观众的感受，看演出看到一定程度，然后就会厌倦，所以在商量这个活动的时候先锋书店跟我说，能不能让我来唱几首歌，我当时口就回绝了，我说我不想唱。因为我现在不想唱歌、不喜欢唱歌，在现在这个阶段。</p>
<h3 id="14-随时准备跨界">14、随时准备跨界</h3>
<p>那么，你既不想演出，唱歌又赚不到钱，你怎么生活呢？</p>
<p>所以这个时候我又想了一个东西，做副产品卖T恤（听众爆笑）卖帽子（听众鼓掌）。</p>
<p>当然，也不是这么直接和简单。这么些年以来我们做了很多副产品大概有加起来二十种吧。最初做的时候其实动机就是刚才讲的，赚点钱，但是做着做着就发现没有赚到钱。大家可能不信，这样一件T恤我们卖一百二十块钱，它的生产成本可能是30或者40，具体我不清楚因为我已经不亲自去弄它了。</p>
<p>其他成本是非常昂贵的，最大的成本是什么？物流和淘宝工作人员的工资。</p>
<p>那么T恤是能赚钱的，但棒球帽没赚钱，那这种T恤赚钱了，那种产品可能不赚钱，所以整个衡量下来，我们整个产品去年的销售额可能就15万到20万左右，利润可能也就是七八万，但是这七八万里，大部分给了工作人员当工资，我的利润就是存货，因为总有卖不完的东西。</p>
<p>这边20件T恤、那边30件衣服、那边还有50个硬盘。我自己的利润全都转化成了实物。所以我们今年上半年的巡演才会想出签售这样的馊主意，签售是我最讨厌的，但我就想把我那些存货消灭掉，因为太多了。</p>
<p>所以当你看一个物品的时候，我操我花了120块钱，这件衣服才值30块钱，我心里肯定不平衡。但是你没有考虑到全局，你不是在我这个位置。</p>
<p>OK ，副产品做着做着就有些新的想法，什么想法呢？</p>
<p>我觉得在做产品的过程中是可以积累经验的。这个经验是用来干什么的呢？就是我时刻准备好有一天我不唱歌了，不从事这个行业了。那么我要去做其他的事情，做什么呢？</p>
<p>从我个人的喜好来讲，假如我不做音乐，给我两个工作去做，我会选择家具厂而不是软件公司，因为我是个农民，我喜欢实实在在的实体，我宁可想办法把一个矿泉水瓶做好，也不会做一个好看的操作系统或者APP。</p>
<p>所以，我做的所有副产品，都是实实在在的实体，从帽子到衣服再到U盘再到吉他谱，每一个东西做的过程中都会有很多经验教训，教训产生于跟各种厂家的合作，产生于面对广大的群众的委屈也好、感慨也好、感动也好。所以我才会不厌其烦地做那么多东西，尽管我知道我没有赚到钱。</p>
<h3 id="15-请尊重版权做个文明人">15、请尊重版权，做个文明人</h3>
<p>在这个副产品……做完副产品之后我们开始意识到版权的重要性，这种版权是相互的，一方面是我们自己的版权应该保护，同时，别人的版权也应该保护。</p>
<p>所以我找了一个律师帮我们处理所有版权的事情，现在包括我们所有的合同，甚至有些对外公告的文字都要律师来过目，比如说一个售票信息，实际上里面有很多漏洞会引起法律的误会，这时候就需要律师来修改它。</p>
<p>我记得去年跨年我们发了一个售票信息的长微博，但是那条微博是我们四个人包括律师在内，花了一晚上时间，从0 .1版本改到8.7版本。</p>
<p>在大部分观众看来这是没必要的，但在我看来是有必要的，为什么？</p>
<p>因为只有你强迫自己做一件事做到极致的时候，你才会把他养成一种习惯，把他做得更好，而法律这种东西，必须是一种强迫性的没有任何漏洞的。</p>
<p>我们现在说到的每一个音乐节的合同，在我看来都是一张废纸，乱七八糟，所以每次我们都把它改得面目全非。</p>
<p>那么我当时找律师的时候，他问我为什么找律师，我说我就两个动机，</p>
<p>第一个我不想别的人侵犯我，第二个我不想我侵犯别人，因为这是一个相互的事情，很多时候我会在无意中有这些侵权的行为，但是有了律师之后我就知道不能做。</p>
<p>比如说以前我们在演出前会放一些背景音乐，但严格按照版权法是侵权的。但是我又没有精力去联系各个版权方，我做不到。</p>
<p>比如说以前演出我们会随意地翻唱一些歌，但是按照版权法是侵权的，后来每场演出我们就翻唱一首，然后还要去申请它的版权，也就是说在版权的问题上，守法的成本是很大的。对观众来说也是这样的。他觉得你现场演出前放一些歌曲他很舒服啊，你演出中唱些歌大家都很开心啊。</p>
<p>但为什么要这样做，同时又不违法，所以后来逐渐地干脆不在现场翻唱歌曲，演出前也不放音乐，另外就是图片的版权。</p>
<p>我们购买了很多观众拍摄的照片，可能价格很便宜，但是我们的确在购买。比如一场演出结束了，我们看到有人拍的照片很喜欢，我可以把它买回来，这个版权是我的。</p>
<h3 id="16-习惯了法律也没那么难">16、习惯了法律，也没那么难</h3>
<p>这些零零碎碎的钱包括刚才讲的为了申请一首歌的版权这种费用，全是乐队整个团队开支的部分，再回过来所有的收入只有演出，所以我只能报价很高，不停地提高价格。</p>
<p>在2010年做了一个官网，把所有的mp3、所有的视频放上去免费下载，然后让大家看着给，实际上这个活动到现在也差不多结束了，因为大家都知道那个网站已经被墙了，实际上它整个的运作在3年左右，我们的收入大概在20万到30万，可能对很多人来说蛮多的嘛，又没有什么付出，在网上挂，让别人下。但实际上不是，我们下坏了好几个硬盘，我们都知道服务器硬盘很贵的。每天还在付服务器的租金，所以这也没赚钱。</p>
<p>建个服务器再付租金再维护然后硬盘还给大家下坏了，其实是没什么钱赚到手，虽然我这个数字告诉大家，这个下载有二三十万的收入，好像是天上掉下来的一样，其实不是。</p>
<p>我是越来越觉得版权其实是各种法律里最普遍的一种，当习惯了这个法律的时候你觉得，其实也没那么难，而且这是应该的。这一个部分的主体就是，副产品和其他，总结来说，就是所有的动机都是想着去赚钱但是最后发现没赚到钱。</p>
<p>但是积累了很多其他的经验，这会在以后我的转行里会有好处，我时刻准备着去转个行，因为如你所知，我的脸皮没那么厚，我不好意思表演着从事这个行业，就是我不想成为一个人民艺术家（听众轻笑），去唱唱卡拉OK去骗点钱，去拍广告。</p>
<h3 id="17-如何管理一个团队">17、如何管理一个团队</h3>
<p>ok，第五个部分，做团队。好乱啊…所有的事情都是做啊做啊越来越多，事情越来越多我就忙不过来了，然后就想到要做一个团队，但是这一个过程是发现，哎，好像是有一个团队哦。而不是今天我要建一个团队，我要找这个人找那个人。</p>
<p>最早的时候其实就是一个人在帮我，忙不过来的时候，我的一个好朋友，认识十几年了，那时候他开始帮我，帮我租个房子、交个水电费啊、发个快递这样的杂事。后来给他的事情越来越多。</p>
<p>一开始请吃饭：帮我个忙，帮我交个水电费啦。后来事越来越多，开始付他钱。帮我把这个事情干了付你多少钱。到后来好吧，我一个月付你多少钱，不管有多少事情，有没有你都去全干了。逐渐逐渐的就成了一个助手。然后发觉一个助手已经不够，又找另一个助手。</p>
<p>然后开始有经理人、开始有设计师、有摄像团队、有音响师、音响团队，灯光师、灯光团队，法律顾问，视频团队这都是在长期的过程中不停地合作。合作得不错，就成了一个固定的成员。</p>
<p>我们现在团队成员除了乐队成员之外有十二三个人左右。乐队大概有10个人，所以整个团队应该是在20人以上。这就涉及到另一个问题，那就是钱咯。</p>
<p>如何维持这二十人的运转。</p>
<p>告诉大家一个数据，可能有些人已经知道了，去年2013年，我的收入有300万，百分之七八十都是演出来的，剩下的百分之二三十都是各种各样来源，比如数字音乐、副产品的销售。但是这三百万最后到我手，利润也就是二三十万，那么剩下的二百六七十万，都到了运转团队里去了。</p>
<p>当然这个钱不是平均分结每个人的，而是各种成本，就是维持这个团队的运转消耗的钱。</p>
<p>所以，很多人都在问我，怎样去建一个团队。</p>
<p>怎样让一个团队运转得更好，其实我的第一想法是，先准备一点钱。</p>
<p>现在我做的很多事情包括演出，就是为了赚钱，因为团队要运转，他的关系是很微妙的，整个过程会越来越累，然后妥协，其实这是好还是坏我根本不在意，不太知道。</p>
<p>但实际上作为我们团队的人，真正到他们手上的利润有多少呢。其实是挺少的。那么大部分钱花哪边去了呢。</p>
<p>维护关系成本，维护个人和这个团队的关系的成本。</p>
<p>成员除了工作人员之外就是乐队，其实乐队的乐手是一直在变动的，这是近三年相对稳定的一年。那么乐手变动的原因有很多，有的是我觉得不合适，有的是他有事，各种各样的。</p>
<p>但是乐队的变动是非常非常累人和痛苦的事情，他不是团队成员的变动，为什么说乐队五个人有一个人换了，所有的工作要从头做起，这不只是钱的问题，更是精力的问题。</p>
<p>我们在2012年，排练了差不多有100次以上，就是因为变动了一个乐队成员，所有人都已经很熟很固定了，但是为了那个人要不停地磨合，那种状态是非常痛苦的。同时乐队成员之间业务能力的高低不平，审美的高低不平，生活喜好的不一样会导致一系列的问题等我来解决。</p>
<p>大家如果有心会发现，全世界没有哪一个乐队能保持十年的黄金时期，同时乐队成员不变动，中国更是如此，乐队成员一直在换人，但是中国跟那边的差异在哪边。</p>
<p>其实我们这边都是因为一些鸡毛琐碎的事、小利导致分崩离析，根本没有谈及音乐理念的不一样。都没有。</p>
<p>无非就是，啊，这个人吃饭永远不买单，这个人从来不带香烟，这个人睡觉打呼，这个人老是泡妞，这个人老是迟到，这样一些事情导致了一个乐队的分崩离析，根本就没有涉及到音乐理念的问题。</p>
<p>所以后来我意识到这个问题之后，我着手的第一步就是保证每一个乐手的利益，至少保证在这个行业里在我这边的利润是最高的。其他的东西眼不见为净。所以乐队才能够运转下去。</p>
<p>坦自说我组了这么长时间的乐队，在南京换了这么多乐手，其实乐队里没有几个人是喜欢我的音乐的，这是他们告诉我的。</p>
<p>但我觉得很正常，观众可能很惊讶你的乐手不喜欢你的音乐，但，是的。这是一个正常的情况，我也不觉得丢人。我对我自己的认知肯定是一个无能的人，观众对我的认知偏高的，同行对我的认知是很低的，这也是一个很奇怪的事情。</p>
<h3 id="18-音乐人也不自由">18、音乐人也不自由</h3>
<p>好了差不多这十年我做过哪些事情呢。</p>
<p>做了六张唱片，做了几百场演出，做了几十种副产品，组了个团队和换了无数乐手。到目前为止，我的困难是什么？</p>
<p>其实不是，其实到现在为止最大困难是社会制度因为这个~government的制度啊不支持一个人勤奋、努力地工作，然后赚取他应有的回报。</p>
<p>尤其在所谓的文化行业里会给你各种各样的限制，比如说第一个，演出审批，这都是扯鸡巴蛋的事情，你办演出演经过他的审批，你唱什么、不唱什么要经过他的同意，甚至你的穿着。</p>
<p>上上个月我们参加了一个大的演出让很多观众说：唉，你怎么唱那么冷门的歌。</p>
<p>但实际情况是我当时报上去六首歌，五首歌没有通过审批，而且理由都是很匪夷所思的，比如说“死”不能有“屎”不能有“手枪”不能有“他妈的”不能有那作为我这样一个神经病歌手还能唱什么呢？<br>
那直接反应就是观众看到五六个乐队都演得挺好，就李志演的什么屌东西。但是我脍炙人口的歌曲我不能唱。你说我能怪谁呢?除了怪这种制度之外。</p>
<p>你想象不出来这都已经21世纪了，还有这样的情况，但这是实实在在的情况。</p>
<p>所以回过头来，我们跨年为什么要选那么一个小场地？</p>
<p>因为场地小可以偷偷摸摸地审批或者不审批。你到五台山试试看。《他们》能唱吗？人民不需要广场…… 《人民不需要自自》能唱吗？《女神》能唱吗？</p>
<p>都不能唱，一半以上的歌都不能唱，我搞鸡巴跨年啊对吧。所以很多事情也只有我自己知道。</p>
<p>当然我经常会在网上发泄这种情绪，就是发泄一种你所在的生存环境不支持你的工作，同时你还认为你的工作是勤奋的是守法的是认真的，这很让人感到心慌。</p>
<p>第二个行业制度。这个行业整个来说是很混乱的。混乱到什么程度呢？</p>
<p>我始终觉得就是一帮没有才华没有素质的臭流氓在那边捣浆糊。这么说肯定有点清高，但是我就那么清高，我就是看不起他们，当然了这样也有好处，</p>
<p>好处就是当你和一群傻逼在同一个行业的时候，你只要稍微勤奋一点，你就会有出头的机会。</p>
<h3 id="19-房租与偏见">19、房租与偏见</h3>
<p>然后说些实实在在的困难就是我已经想了两三年要做一个工作室，但是找不到合适的地方。<br>
前段时间有人想投资我做个Live house，我也找不到合适的地方。我也在找，为什么找不到呢？<br>
房租太贵啊。</p>
<p>比如说，一个工作室，我需要的面积要在一百平米以上，层高要在五米以上。那这样的环境要好，不能是地下室，要多少租金？</p>
<p>本身这工作室是不带来直接的经济利益的。我还要付水电费还要装修，我还要添置设备。如果说以录音为标准的话肯定一百万都不够。那如果只是排练，怎么也得五十万以上，然后再加上房租，我一年哪来这么多钱投进去呢？</p>
<p>在南京找一个可以排练的地方，不说设备，就像让我们十几个人待下来的地方都没有。没有这个环境，所以我只能在家戴个耳机“排练”。你想嘛，都已经这么红了连排练的地方都没有，找谁说理去。<br>
想自己建一个排练房没钱建，租金你都付不起，一年十万的租金，附带条件还不能扰民。所以去年跨年前我们去上海排了五天，排了五天花了五万，一天一万的水准，我找谁说理去？</p>
<p>你就说这live house，现在国内有几个livehouse是赚钱的？赚不了钱。30块钱买一张门票，十块钱买瓶啤酒，你就可以在里面待两小时，还把椅子搞坏了。</p>
<p>你门票卖贵了吧，观众要叫：卖那么贵干嘛？我们学生我们穷。</p>
<p>学生你用iphone 4干嘛？有病。</p>
<p>你看电影买牛仔裤吃饭的时候从来不在乎钱，看个演出涨了十块就跟我叫。当然了又回过来，这种破演出五块钱都不值，你凭什么卖十块钱。所以这个里面永远是三角矛盾：舞台上的人，观众和场地方。</p>
<p>前段时间接触了好几个有理想的人，他们想投钱给我做livehouse，我们谈得很愉快，大家都拍着胸脯说没问题，等着我去找房子，然后等了两个月一点眉目没有。</p>
<p>昨天还打了一个电话，有一个地方要转让，人家问你要做什么，我说我要做个音乐酒吧，他说哦谢谢对不起我们不做。</p>
<p>每次去跟别人解释这个房子干什么用，我说工作室，问什么工作室，我说音乐工作室，对方就不知道该怎么说了。</p>
<p>总的来说这个行业还是被歧视的，但是这种被歧视是有道理的，是因为这个行业的从业人员素质太差，这种素质差不是头发长不长留个光头带个墨镜的问题，我可能说多了又会有非议。ok！这些实实在在的问题、困难在面前，一直在有，时时在有，可能拍大腿也过去了。</p>
<h3 id="20-演出门票贵羊毛出在羊身上">20、演出门票贵，羊毛出在羊身上</h3>
<p>讲今天的最后一个问题，也就是为什么中国的演出门票这么贵。</p>
<p>大家想过这个问题吗？<br>
举几个例子啊，我在香港看过大概有三四场演出，基本上也就两三百港币，好点五百到六百。我在纽约看的罗杰沃特斯（注：平克弗洛伊德乐队贝斯手，乐队的创始人之一）的演出，也就是一百美元，而且我跟罗杰沃特斯老师的位置也就我到那个柱子那边这么近，最前排。</p>
<p>包括我去看莱昂纳德·科恩（注：伟大的诗人、歌手，U2主唱赞颂他为摇滚界的拜伦）等很多国外大牌的的演出，门票其实是非常便宜的，但是在国内为什么这么贵？</p>
<p>连李志的演出都会卖到两百三百。为什么？其实你们想过问题没有，为什么我们的演出会这么贵。因为我们的演出成本太高了。</p>
<p>这个成本是什么呢？</p>
<p>一部分是硬成本，一部分是软成本。这个软成本啊，我跟你说，你在五台山想开个演出，可能百分之二十到三十的票就拿出去了，而且是没有理由没有借口没有收据地拿出去了。</p>
<p>消防、公安……因为现在不给收钱了，那他们就要票，那他们这些票都拿去干嘛呢？搞到黄牛市场。OK，这是一种成本。第二种成本，经常会碰到演出被取消。实际上一场演出被取消之后损失最大的是主办方，因为他场地定金交了，设备定金交了，所有的费用都付了，他非常不愿意被取消。但是这种被取消是他完全不能够控制的。</p>
<p>很多都是政府的行为，一句话，某个人的一句话。这样的风险导致他必须把它的利润搞得非常高，才会继续做下去。第三个，整个这个行业。我们说非主流音乐这个行业。他还是在一群没有钱的人之间转，我相信在座的没有几个是有钱人，有房子的有几个，对吧。大部分的是没有钱的，对吧，是这样的吧？是吧？</p>
<p>但是它的支出是比其他行业高很多的，它不能和电影这样的行业比，但你跟那些画画的、写作的这些行业的去比，一把琴两万，一套弦两百，排练房一弄，录一张唱片二十万，这些成本非常之大的，只能通过高收入来分担。但是实际上这个音乐行业本身能赚到钱吗现在？</p>
<p>我说非主流音乐行业。主流行业他们会赚到钱。而且他们演出赚的钱已经是收入的很小部分了。总的来说就是在一个不合理的制度的国家里面，你要做演出，你的成本会高的离谱。而且这种成本会是让你窝火的高成本，你不是那种心甘情愿的，或者说理所当然的。</p>
<p>所以，现在大家能理解我为什么坚持在一个七八百人的小剧场里搞跨年，而不去大的两三千人的体育馆搞吗？</p>
<p>风险、成本、不可控的因素，到时候你就会看到一个，如果说那样搞一个跨年的话，你只能看到一个很华丽的、普通的商业秀，不排除我以后会那么做。但是现在我还是想纯粹一点、再纯粹一点，至少我要决定我能唱什么，我不能唱什么。</p>
<p>如果说连这个都不能达到的话，那我只能去赚钱，所以……总而言之今天讲得挺乱的（听众鼓掌）我确实不是一个很擅长讲话的人，我只擅长在网上跟人扯淡，当然……讲得断断续续的。</p>
<h3 id="21-我更需要冷静的歌迷">21、我更需要冷静的歌迷</h3>
<p>最后总结一下就是，我是一个很普通的人，我没有为我很平凡的人生感到自卑或者骄傲，我就觉得我的运气还不错，我比一般的人勤奋，然后我才能够得到一些让我感到恐惧的大家的关爱。<br>
但是不管如何，我还是坚信我跟诸位是平等的。</p>
<p>你们消费我一定要理性，我消费你们我也很理性，我们一定要是一个理性的认真的态度去对待外面的世界。我希望我能够尽性，有一天找到做音乐的乐趣，或者我能够找到一个新的乐趣让我去转行。</p>
<p>这差不多就是我今天要讲的东西。</p>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[使Git忽略文件模式( chmod ) 的更改？]]></title>
        <id>https://merpyzf.github.io/post/shi-git-hu-lue-wen-jian-mo-shi-chmod-de-geng-gai/</id>
        <link href="https://merpyzf.github.io/post/shi-git-hu-lue-wen-jian-mo-shi-chmod-de-geng-gai/">
        </link>
        <updated>2020-06-23T03:15:29.000Z</updated>
        <content type="html"><![CDATA[<p>通过执行如下的命令即可👇</p>
<pre><code>git config core.fileMode false
</code></pre>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[李志自传]]></title>
        <id>https://merpyzf.github.io/post/li-zhi-zi-chuan/</id>
        <link href="https://merpyzf.github.io/post/li-zhi-zi-chuan/">
        </link>
        <updated>2020-06-12T13:21:36.000Z</updated>
        <content type="html"><![CDATA[<h3 id="1">1</h3>
<p>第一次试图用吉他去泡妞是在高二：那年冬天我拿着红棉吉他在她窗户底下唱《同桌的你》。地震时期的某天狼哥给我短信说：逼仔保重。我没敢告诉他当时我正在弹这首歌。</p>
<p>这个姑娘不是我的同桌。老子从初中开始就没有和女性同桌过。高二文理分科，她从某班调入我们班。她长相平平却眼神勾人。她现在的身份是我高中母校的老师，同时是我高中同学的夫人。我这位高中同学，啊，就是我试图泡的这位高中女同学的现任丈夫在高一和我同桌。所以每次我听到《同桌的你》这首歌的时候都要冷静的理一下头绪才能不会没有头绪。各位看官就不必理了，各位看官同样不必去人肉。人家夫妻生活和睦有家有子。看官试图人肉的结果就是我写的越来越隐晦，最后说不定就是大段的微积分解题。</p>
<p>当年的泡妞计划失败，但故事并没有结束。高中毕业后我考入南京某高校，她保送到南京某另高校。在得知保送成功到高考结束的这段时间，她和高中另一男同学关系暧昧。后来这位男同学和我上的同一所大学。但是我和他的关系始终没有好过。没多久我们就不联系了，直到现在也是如此。</p>
<p>大学期间我和她相互写了不少信件。可是我水性杨花的有了心上人。所以，信件没有暧昧。我去她学校她请我吃饭，她来我学校我请她吃饭。相敬如宾举案齐眉。她介绍了不少同学给我挑选，但我就是一个都没看上。此刻我回忆她那么多燕瘦环肥的同学，只记得一个长腿妹妹。但这个印象不是因为腿长，而是她念到了数学博士。我记得这位同学姓景色的景。还有，在他们毕业典礼上我帮这位同学伴奏过歌曲《执迷不悔》。</p>
<p>啊，看官们要看xxoo？要看老汉推车或者老树盘根？别急，我们不能直接从百万雄师过大江说起，我们先看下史前文明，看下老子20岁之前不知道女人是两个乳头还是三个乳房的纯洁年代的男女关系。我的同学小翁曾经和我说搞女人和搞银子一样，一旦上路就会变得非常简单。最难的是第一个女人和第一桶金。本来我不应该相信小翁，但是看在他一年几百万的身价上，我想还是相信的为好。</p>
<p>我的第一个女人大约是在千禧年冬天发生的。本人22岁。在这之前还有些事情要说。</p>
<h3 id="2">2</h3>
<p>大学期间我看中的第一个姑娘是我的同班同学。她师出名门高贵典雅娇小可爱。我在第一时间不要脸的向她表达了爱意。但到最后时间都没有得到她的青睐。最后一次见她都是7年前的事情了。据校友录消息，伊移居海外结婚生子。</p>
<p>本人和伊最亲密的接触是大一秋天我们班去郊游，伊坐在阳光明媚的草坪上拿着冰激凌纯属客套的问我，你吃吗。我居然不要脸的说：好的。然后伊无法琢磨的脸色用小棒棒掏大便似的掏了一坨放到我嘴里，我不要脸的一口吞下，祝枝山似的心满意足躺在阳光下同时尴尬的要命。在随后的几年里，同学们见面打招呼说的都是：你吃吗。</p>
<p>吃你妈逼。一般老子都这么回答。一般人都不知道敏感而脆弱的人的可笑或者不可思议的行为往往只是因为短路。有的人选择沉默，有的人选择报复。有的人喜好拿别人不愿提及的东西开心，有的人喜欢表现自己的优越感。敏感伴随着焦虑，我们小心翼翼同时错误不断。我没有成为马加爵不是因为我懂得克制，而是我的同学还没到那个地步。我没有拿着斧头追老师，是因为学校里禁止骑自行车。在幻觉里，我想最好的办法是离开。</p>
<p>这位同学智商超群又桀骜不驯。她做过一些在那个时代在我看来都非常超前的行为，但这不影响一直以来我对她的敬仰，这是对智商和性格的敬仰，就像我对王小波先生的敬仰一样。大学毕业前这位女同学和同班一位男同学进行了黄昏恋。然后短暂的欢愉，然后各奔东西。这位男同学几个月前和我在小酒馆边上的咖啡馆喝咖啡，同行的还有他的夫人和我们的另一位同学。他和以前一样喜欢穿着运动短裤，和以前一样智商超群出口成章弱不禁风。</p>
<p>我和这位同学分别和这位女同学之间的事不是秘密。但是我们坐在一起从来没谈过这位女同学。男人之间处理事情有男人的办法。打打杀杀斗嘴斗笔那都太低级，男人之间的解决问题就是一个眼神，顶多加几道线性代数题。</p>
<h3 id="3">3</h3>
<p>大学同班女同学的替代品是第一任女朋友的大学女同学。头晕？这样，我们把高中女同学命名为A，大学女同学命名为B，第一任女朋友命名为C，C的大学女同学命名为D（以后出现的人物我们以此命名）。于是我们这样说：B的替代品是D。</p>
<p>我对B心灰意冷时，D石崩而出。我和D的认识是因为C，我和C的认识是因为我弹吉他。其他的关于C的事情我决定不描述——虽然我们之间伴随着你们感兴趣的xxoo。原因我也决定不说。</p>
<p>为什么说D替代了B，因为她们实在太像了。怎么个像法？用著名摇滚巨星朋克张先生的说法就是：老李你他妈的口味就一直是这个操性。这个操性就是：娇小可爱安静甜美。她们之间的不同是D远没有B聪明，D比B更叫师出名门。D的祖父是我们学科的开山鼻祖，也是我们系的老院士。<br>
D的祖父的弟弟是大家都知道的一个大人物。绝对的大人物。</p>
<p>我和D有过亲密接触，这些接触包括几次或长或短的接吻，几次下手太重或者下手太轻的抚摸。D的胸部很丰满，但是我看重的不是这些。在月光明媚的元宵节，我们第一次接吻的时候我的手是放在她的臀部而不是胸部。我感到下体阵阵疼痛，但没有心思去解释那疼痛的原因。</p>
<p>到现在我都搞不清楚D是怎么想的，到现在我都不知道D到底是怎样一个人性。当然，我现在不用考虑这些问题，就像我不用考虑我和D是怎么开始的怎么结束的，这些没鸡巴意思。曾经有人说过我总是对事物存在一厢情愿的幻想，强迫自己屏蔽现实。可是，现实和幻想到底哪个是真实的鬼知道。我只清楚，我被D伤害过。这种伤害不比“十三月的果儿”的伤害来的简单。但是男人嘛自己的苦自己忍受。</p>
<h3 id="4">4</h3>
<p>这个星期老子睡得早起得早，这个星期老子一直在和感冒抗争，今天一早老子起床洗床单，外面阳光明媚，老子上身下身肮脏不堪，老子固执的要等床上干净了再把自己搞干净。所以，老子一直在写。在今天早晨平武又发生了余震的情况下，我同事把电视机的声音开得非常大，逼迫我用耳机塞住音道，一直循环着听《米店》。玮哥徐志摩式的眼镜在脑子里打转。他说：逼仔，朕诚惶诚恐。而我又何尝不是呢。而我现在开始写xxoo。</p>
<p>洗衣机里的这条床单是紫色的，22岁的那条床单是蓝色的。那年冬天我和E纠缠着身体，布朗运动把蓝色床单扭曲了。还有无数个夜晚，我左手拿着徐若瑄写真集右手抚摸着下体，那条蓝色床单也扭曲了。浓痰般的精液喷出的时候我往往仰天长啸着烟熏黄的天花板和蓝色的床单。当我看见蔚蓝的赛里木湖，我本能的躺下勃起22岁一整年的鸡巴而精液像远处高耸的雪山。</p>
<p>pk14重复着唱道：烂掉吧烂掉吧。</p>
<p>E是我朋友的前女朋友。那天她在我屋里呆了一整天。时而说些不咸不淡的话，时而翻着我桌上的书。后来天越来越黑，我知道她不打算离开了。后来我说你睡床吧我坐着看看书弹弹琴。后来我受不了冷和困也进入被窝。我在左边她在右边。我们平躺着，她没有脱光她的衣服，我也没有。然后我就把手放在了她的腹部。她像个木偶没有动作没有声音，我捣鼓了半天。</p>
<p>在进入的时候我说我是第一次，她不置可否的冷笑了。白色的精液夹杂着红色的血迹在蓝色的床单上，真他妈触目惊心的和毕加索一样。现在玮哥唱道：一定有一些马想回到古代。关于早泄，别看教科书，你只要变成那只马找到我22岁那天晚上。但对我而言22岁不是古代。我还不想回去。</p>
<p>一年后我从罗庄搬走和人同居在兰园，一天晚上木楼梯传来沉重的脚步声。我和同居人目瞪口呆的看着E脸色通红酒气熏天的走进来。她坐了一分钟，微笑着用同样沉重的脚步声走下楼梯。后来，我听说E在宿舍门口高分贝的喊道：来操我吧。同居人在几年后说起那天晚上的脚步声，我告诉她我的第一次性生活。她恍然大悟。</p>
<h3 id="5">5</h3>
<p>那条蓝色的床单是F和我去洗的。</p>
<p>具体情节是：那天晚上F坐在我的自行车后面，我们迎着凛冽的寒风去交专的洗衣房。F从上海过来，在我那住了一个星期，没日没夜的做爱。</p>
<p>她帮我洗头，我给她做稀饭。我们的性生活还算和谐，我没有早泄，当然也没有现在这么伟岸。我带她去吃了一些南京的饭，然后她回东北老家过春节。</p>
<p>就在刚才，著名乐队的著名经纪人Y小姐在msn上和我说“哈哈哈你可以的”。一个星期前在宝安机场，Y小姐送我一条巨大内裤，我不知道Y小姐是嘲笑我体重的反弹还是道听途说对我的性器官充满信心。这算是爆料不？在机场的时候我和Y小姐戴着墨镜拍了几张绯闻照。我对我们的表情深表认可。不过，我和Y 小姐是纯洁的友谊关系，就像我和Y小姐的好朋友G小姐和N小姐一样。</p>
<p>春节后F又到了南京，一个星期后回上海上学。在车站的时候我觉得很难受。然后我们大约有好多年没有联系。然后有一年我在广州和她打过一个电话。然后有一年冬天我在北京和她见了最后一面。那次是在清华东路附近我的住处。我们坐在我们的床上，说了什么都记不得了。她戴着长辫子的毛线帽子。然后我们礼貌的说再见。我看着他消失在傍晚的路上。再后来她说她喜欢我做的东西。</p>
<p>F的家庭情况并不好，她的身体也不好。她是那种先天的悲观主义者。她是那种先天的善良之人。我知道，我和她不明不白的两个星期对她存有伤害。但是我也不是仅仅为了做爱。我冲动的买过飞沈阳的机票——虽然未遂，我有时会想起她的背。对于不良乐手，这是多么难得的事情哇。但是我也不好说我爱过她。至少我不好意思这么说。关于我们的关系，她曾隐晦的提起过，然后我隐晦的否决了。</p>
<p>F的最大特点是她给你回复的短信往往让你琢磨不透，然后仔细一想，原来她是在回答你一个星期前发过的短信。虽然我的记性特别好，但是我还是很少发短信。我总觉得像她这么一个人活着很难，但我不能支持她去死。我也想不出她最好的生活的方式。总之我们若即若离的联系，她一成不变的语气和我一成不变的语气就像我们一成不变的没劲的故事。</p>
<h3 id="6">6</h3>
<p>贩卖打口碟的那段时间我认识了不少人，其中一个是G。每天下午，我骑着车去她们学校门口摆摊，和缺斤少两卖水果的阿姨，卖5块钱一个耳机的大哥打的火热。有时候我的好朋友邦德会和我一起去，我们色迷迷的在灰尘里对姑娘们挑三拣四意淫口淫。有的时候邦德太累了，我就带着琴一个人去。</p>
<p>关于带琴做生意需要说明的是：因为G的学校在郊区，人迹罕至，同时校门口的那条路又宽又脏，所以我才会厚着脸皮用吉他揽生意。但后来实在是受不了同行大哥天天叫老子弹《单身情歌》终于不带。</p>
<p>有天G蹲在我的摊子面前挑CD，我轻而易举的看见了她红色的内裤。然后她问我有没有Jeff beck的唱片，我拿了Jeff becklly滥竽充数，她也没有明辨是非。最后我们自然而然的交换了呼机号码。</p>
<p>后来她和我联系上，我们在G学校附近荒无人烟的马路上乱走过很多次。我试图把她搞定但总是未遂。甚至有一次她睡在老子床上一夜我都没有一马平川。我的好兄弟邦德说，最好的泡妞方法就是挑起她的原始欲望。他这么说有光辉的明证：搞定一个女同性恋。但是，我始终做不到，有一个问题我没有和邦德兄探讨过，那就是：难道用语言也可以挑起女人的原始欲望么？这是需要多少个余秋雨似的古典文学哲学西班牙斗牛知识兼口才啊。</p>
<p>有一次在电话里G告诉我说她要去和一个网友约会。我不是她男朋友，自然也无权干涉。几天后，她给我打了电话，意思是不想和我再有联系，希望我好自为之不要骚扰她。其中夹杂一些难听的话，“你连大学都读不完能有什么出息？”之类。我伤心并且愤怒了。后来有很长一段时间我和G没有联络。然后不知道什么时候她又跳了出来。</p>
<p>这个时候G在念研究生，我和她见过几次面，每次我都会想起那天晚上她在电话里侮辱我的话。我耿耿不能释怀，是的，我们没有办法灭绝别人的评论，因为我们本身也无法断绝评论。活着，不管是声名显赫还是默默无闻，都难以逃脱舆论。这是让人愤慨的事情。</p>
<h3 id="7">7</h3>
<p>有一次G带我去她宿舍玩，宿舍里没有人，G撅着屁股趴在桌子上捣鼓电脑，试图给点合适的音乐，我从背后自然的抱着，和她一起寻找。她的超短裙很短，天气很热，在扭曲的时候我像往常一样做着边缘的抚摸，然后悄悄顺势脱了她的内裤。接着迅速拉开拉链，迅雷不及掩耳之势的插入。G惊恐不已，因为我们之间有过无数次类似的边缘性行为都被她化骨绵掌般顺利化解，只留我空空的冲天鸡。而这次她疏忽了，她有些呆滞的试图推开我，这都是徒劳。接着她边嘀咕边配合，夹杂着我分不清真假的呻吟。甚至一瞬间我怀疑这是不是强奸。</p>
<p>我承认在射精的瞬间我内心充满了罪恶的报复的痛快。精液顺着她的臀部滴在地板上，就像那天晚上她说的话那么肮脏。然后我穿上裤子，走出了宿舍楼，在一个超市喝了一盒酸奶。内心空空荡荡，六月的天空晴朗无比。</p>
<p>几年后我到了广州，有一天在qq上遇到G，正好她也在广州，好像是为了和一个中年男人约会，出了点意外她问能不能到我那里住，我犹豫了一下说没问题。当时我住在小翁那。她到了赤岗车站之后我去楼下接她。那天晚上小翁住在一个房间，G在另一个房间，我在客厅。有一次我故意走进她的房间，她抬起身子，睡衣下小小的乳头格外清晰，用那种眼神看着我。我没有上钩，含蓄的转身走了。</p>
<p>那是我最后一次见G。</p>
<p>后来小翁和G保持着联系。他们在南京见过好多次面，至于见面之后的事情他没有和我说。我估计小翁搞上她和搞不上都合情合理，因为小翁既有钱又没多少文化。有一次小翁还问我要不要一起吃饭。我说算了，我不想见。</p>
<p>在各种渠道我听到过G的各种事情，她在我眼里的形象最后变得很糟糕。我对G所在的学校也深深的产生厌恶，这种厌恶或者说鄙视直到现在还没有消失。不只是G一个人，我认识的很多G校的人，他们都有点不踏实，都有点小才华，都有点高傲，都有点看不起鄙校。</p>
<p>G校和我有关系的女人还有两个，一个H，一个是I。下面我们先说说H。</p>
<h3 id="8">8</h3>
<p>我认识H，是因为一个徐姓的男性朋友，这个朋友也是我做打口碟生意时认识的，几年后有一天他找到我，希望我帮他录几首自己的歌。H是徐姓朋友的同学，在这个歌里面唱一些和声。我对H算是一见钟情。</p>
<p>录音结束后我没有机会见到H，有一天我和我的老朋友在汉口西路聊天，说起我对H的想念和赞美。气场越来越怪，我对他说，我感觉H就在边上不远处，一分钟过后我目瞪口呆的看着H拎着超市袋子从身边走过，很礼貌的和我打了招呼，优雅的走过。这是发生在我身上最灵异的事件。</p>
<p>这之后没几天，我去了苏州，然后转道上海到了杭州。在浙大呆了几天去了广州。在广州的那段时间，我天天吃着炒河粉坐在小翁的落地玻璃前看着外面车来人往。天气非常之炎热。有天中午我在看书，徐姓朋友打通了小翁的手机。他说要录一张校园唱片，问我有没有兴趣。我说H参与吗，他说她是助理。于是第二天我就坐上了回南京的火车。</p>
<p>H拒绝我拒绝的相当彻底。</p>
<p>那些年，是的有那么些年。我像条春天的丧家公狗一样不停的遇上姑娘，不停的被拒绝被侮辱，不停的作践自己。用星爷的话说：“我是一个泡不到妞的可怜虫”。相当不解啊，不就是穷么，不就是落魄么，不就是没念完大学么，不就是不帅么。为什么没有一个人看的上。为什么所有人都把他的倾述当作有病。不喜欢也就罢了，为什么还要侮辱要讽刺，难道就是因为说了我爱你么？</p>
<p>很多年过去了，李逼这条丧家犬莫名其妙的小红了，能轻而易举的泡到妞了。<br>
可是姑娘们你们知道么，除了声名，他什么都没变过。<br>
你们知道么，那些给他带来声誉的歌都是在你们看不起他的时候写的。<br>
你们知道么，看着现在你们暧昧的眼神，他想到的是你们以前的冷酷。</p>
<p>为什么。这他妈是为什么呢。<br>
为什么五年前你把他当傻逼，五年后你就把他当神。</p>
<p>我在I的宿舍里住过三天。她有一个面朝大海的阳台，飞机不停的从校园上空飞过，黄昏时经常下雨。回来后我写了一首歌。我们还去过一个岛屿，我们吃过芒果冰，我们做爱很少戴套。我一直怀疑她偷偷的流产过，但I坚决否认。我们冲动的决定谈恋爱，然后很快我又冲动的终止了恋爱。她去意大利帮我看了圣西罗球场，她在普林斯顿给我拍了很多照片，她从罗浮宫给我寄来彩色的明星片，她跑到天河城只为了和我喝杯咖啡，她做了我喜欢吃的红烧肉，结束的时候她又一个人默默承受。我呢，除了精液似乎什么都没留下。</p>
<p>对于I我是忏悔的。对于I我的内心非常纠葛。我曾经幻想着我在沙发上看书，她在做家务，有个孩子在弹钢琴。我曾经幻想过婚姻，我曾经幻想过郊游，而这一些在今天看来只是可笑和卑鄙的故事。我和I的父亲通过电话，这是唯一一次和女性朋友的家人说话。电话的缘由是他写了首歌，和我探讨一下编曲录音。事后I和我说她父亲对我印象不错，我也对他印象也挺好。</p>
<p>我和I之间断断续续的若即若离的关系导致我找不到一个书写I的好办法。时间错综复杂，事件隐隐约约。I用藏珠于渊来表达她的心情。我呢？我相信如果以后的生活或者人们说的来世存在报应的话，那里面一定有I的一份——就算我再次对神明的娜姐发誓我爱过I。</p>
<h3 id="12">12</h3>
<p>我在昨天明媚的早晨写下第一个字开始，就做了两个小决定。<br>
一，有些人尽量不写。<br>
二，学习娜姐言无不尽的高尚品德。</p>
<p>我的第二任女朋友现在上海，前些年结了婚。分手后我们再也没见面。一年会有三四次短信：有时她告诉我在布达佩斯，有时她问我星光现场在哪里，有时她祝我生日快乐。</p>
<p>豆瓣达人“造波浪”是我的朋友，他在上海，他女朋友在南京。他们经常往返于沪宁线约会。</p>
<p>现在是吃饭时间，让我们文艺的听一首歌。这首歌是她去年冬天推荐给我的。</p>
<p>《好久不见》<br>
我来到你的城市，走过你来时的路<br>
想象着没我的日子，你是怎样的孤独</p>
<p>拿着你给的照片，熟悉的那一条街<br>
只是没了你的画面，我们回不到那天</p>
<p>你会不会忽然的出现，在街角的咖啡店<br>
我会带着笑脸回首寒暄，和你坐着聊聊天</p>
<p>我多么想和你见一面，看看你最近改变<br>
不再去说从前只是寒暄，对你说一句<br>
只是说一句，好久不见</p>
<h3 id="13">13</h3>
<p>某前女朋友刚才很气愤的质问我为什么要写这些东西，她以为我做的一切都应该为了音乐，她说她不懂。其实我也搞不懂为什么要写？就像我不懂为什么要搞这行。但老崔唱的“反正事情已经重新开始就不能够怕乱”。李逼怕过什么？搞乐队都不怕他还能怕什么？反正生来就不要脸，反正是不要脸的生来，他有什么好怕的！</p>
<p>如上文所述，有那么些年李逼穷困潦倒没有尊严。他经常走在深夜的街头寻找一张睡觉的沙发或者地板。他经常走在明媚的午后寻找一个盒饭或者面包。没有人知道他为什么，没有人同情在意和理解他。他抬不起头，脑子里经常出现一些问题，出现一些幻觉。我要把他说的很凄惨吗？不可能，因为现实不是文字所能描述的。</p>
<p>经常有一些有钱同学的饭局，陌生人问他做哪行，他吱吱呜呜低头吃肉。经常有一些春节，亲戚们问他今年赚多少钱，他吱吱呜呜低头吃饭。经常他忍着饥饿婉拒好意的饭局邀请只是因为没有一块钱坐车，经常他不好意思当着有钱人的面拿出红梅只能跑到厕所抽两口回来。他避免人多的场面，他希望自己是一团空气，他祈祷所有人都看不见他，那样他就不要说自己在写歌，没钱录音。他是这个社会最底层最懒惰最沉默的一份子。仅有的几个兄弟他都不能说太多。他自卑到他自己都无法想象的地步。他坐在街头，看梧桐叶一片片落下，他坐在街头，看人们来来往往。他幻想着一天飞黄腾达然后用钱去购买失去的尊严和青春，用钱去购买失去的孝顺和乐观。他后悔走上这条路同时又不甘半途而废。</p>
<p>他和所谓的摇滚圈始终若即若离。他看不起那些靠家庭或者靠女人的人用着光鲜的设备做着难听而装逼的声音。他在03年看到那些装逼装的不像样子的乐队在迷笛的舞台上接受傻逼朝拜的后现代景象从恶心感到幽默。他看到一个又一个傻逼发行唱片，一个又一个傻逼在一个又一个名义下巡演，一个又一个傻逼睡了一个又一个相同或者不同的女人，他看到一个又一个傻逼在不同的场合演着一成不变的编曲和曲目，还有一成不变的在家修改了几宿的台词，一成不变的在家对着镜子排练过的动作。他没看到几个真正做音乐事情的人！他看到乐手去化妆而不是调音，他看到酒吧没买设备而是更换招牌霓虹灯。他对对这个国家，对这个行业深深失望。</p>
<p>什么鸡巴”善良的人悲伤的哭泣“？傻逼！他们就没有善良，他们就没有悲伤，他们就算哭泣也是因为没有搞定那个女人！他们早就忘了自己辛酸的生活！啊，这是一个什么样的年代啊，朋友！啊！</p>
<p>您老明白了吧，你该明白，突然面对井喷的议论和关注，他是多么的不适。突然，他发现自己正在变成他所鄙视的那些人，他是多么的崩溃。他决定把自己搞脏，他决定把自己往猥琐的道路上指引，这样他才不会在一个人的夜晚感到太多的恶心。</p>
<p>女人，女人那么贱而暧昧的笑着好像她从长阴开始毛就在等他似的。男人，男人那么虚伪的勾我肩搭我背好像我们一直都是好兄弟。好你妈逼！老子才没有你这样的兄弟！你他妈认识老子才几年。你知道个鸡巴！</p>
<p>啊，他只能僵硬的微笑。内心像吃了李宇春一般的恶心。回到家吐啊吐，然后发疯的射精购物抽烟。太不可思议了。一日黄袍加身众生百态重生。老天爷是猥琐的，他肯定是睡着了。否则他不该给我这样好吃懒做的人现在的钱财和声望。他应该像以前一样把我压在他鸡巴和屁眼的最中间没有一丝阳光。我是多么的鄙视之！</p>
<h3 id="14">14</h3>
<p>在写大家感兴趣的淫荡生活之前，请允许我代表我个人以及翘首以盼的各位看官感谢计算机的鼻祖——伟大的冯诺依曼先生，然后我们再感谢互联网的鼻祖 ——光荣的Tim Berners-Lee，接着感谢操作系统的鼻祖——正确的比尔盖茨先生（可能不是鼻祖）。最后感谢伟光正的cctv和三个代表。这个时候，我想起了我的偶像，胡适之先生，他说“每个人都应该写自传”，此刻，这句话显得更加的光芒万丈！</p>
<p>我的大多淫荡生活和一个兄弟有关，这个兄弟和我患难与共，但现在没有同享荣华。我们共难的那几年，爱因斯坦都不会想到会有今天的好日子。这就是刚才感谢那么多人的原因，当然三个代表和cctv不是人。</p>
<p>那时候我们总是在一起泡妞，有时两人有时三人四人。没银子没相貌自然成功率相当低。值得一说的是一次被我命名为“意外”夜晚。我和这位兄弟还有五哥，三人在成贤街包夜。下半夜五哥成功的约了个妞去华侨路喝茶。我们点了最便宜的茶聊了半天文学，当然是李逼主聊，他俩陪聊。看着外面天色渐亮，两位兄台一点都没有撤走让我独吞的意思。我只能勇敢的邀请该妞和我们一起开房睡觉。让人意外的是，伊爽快的答应了。</p>
<p>别急，这次没有4p，也没有3p。你们不能太过期盼，邪恶的毁了李逼诚实的好品质。</p>
<p>这位兄弟付了订金，五哥用身份证登记好房间后，我当场就正义凌然的派五哥去买煎饼，这位兄弟去超市买牛奶和香烟。进入房间后伊去洗澡，我躁动不安如万马过衢州。操余秋雨的，让人再次意外的是：妞还没洗好，两位兄台已经气喘吁吁一脸坏笑的满载而归了。我伤心失落顿时阳痿的瘫倒在床上，他们俩躺在一张床上。虽然我们在一起吹过对无数次群p的美好想象，但感觉群p真正要来临时我还是能感觉到一种奇怪的无法言说的灰常大的压力。</p>
<p>伊洗好之后裹着巨大的浴巾很自然的躺在我身边。我们四人望着天花板有一句没一句的聊着，热腾腾的早饭夹杂着香烟和劣质洗发水的味道弥漫着房间。一切如梦境一般，迷迷糊糊中他们三人打起了轻重不同的鼾。我起身喝了一盒酸奶，站到洗手间水龙头下面，任凉水冲刷。眼泪眼屎意守丹田。</p>
<p>后来和J进行着断断续续的邮件沟通，借助于伟大的金山词霸得知伊在某国际著名广告公司就业，长期沪港两地逗留。再后来她给我打电话发短信。有些短信和电话已经是赤裸裸的调情了，不幸的是，这些短信被当时的女朋友发现。她气愤万分，我也羞愧难当。</p>
<p>我去过一次上海和J约会，托她的洪福，第一次住了五星酒店。我们借住于笔和纸进行了愉快的交流，她给我讲述不幸的小人生和丰富的世界各地的游学生活。她说以后要亲手给我拍纪录片。我说，我又不是毛要纪录片干嘛。后来她给我看她牛逼的各种古董级摄影摄像工具。反正这些东西我很不懂，也不晓得牛逼在哪里，看她那么兴奋得意的样子就姑且认为确实牛逼吧。</p>
<p>总之，那晚的交流很愉快，非常的开阔了眼界。因为没带安全套，所以没有射。当时我就纳闷了，都他妈五星酒店了咋就连个套都不提供呢？！这怎么超越万恶的资本主义啊。第二天一早J去了伦敦，我醒后回南京，本指望能退点押金吃个中饭什么的，没想到J在此酒店是长期包房，退房不用押金这类高级玩意。</p>
<p>又过了一段时间的某天早上突然接到J的电话，她说刚接到任务马上从香港飞北京，问我有没有时间去。我说时间没问题钱有问题，而且火车去的话要第二天早上才能到。她说她给我打钱，我竟然没有犹豫就把账号给了她。然后电话订机票。在起飞的时候我突然觉得自己像只鸭子。而且是会飞的鸭子。</p>
<p>我们几乎同时到了首都机场，她约了某当红男演员在咖啡馆谈合作事宜，我坐在隔壁的桌子上喝着并不好喝的铁观音研究这位当红男演员的裤子为什么有一坨油渍。后来我们去了王府井附近一家五星酒店，我第一次知道从机场进市区原来也可以打车。那天晚上我们同样聊的很开心，同样纳闷的是同样没有安全套，于是我同样没有射精。不同的是，J和我侃侃而谈机场当红男演员和另两位与她们公司有过合作的当红男演员勾引她的细节。我们哈哈大笑。第二天各奔东西。</p>
<p>最后一次是J来南京看展览，我们在火车站边上的酒店大堂吃了点东西，时间到了她就披上黑色的风衣走进了检票口。那天以后为了顾虑当时女友的情绪，我下定决心断绝了和她的联系。可以说，和J的事情百分之八十由于好奇，百分之二十由于疲惫。但不管怎样，在她身上我学到很多东西。在她开阔的视野里，我越发觉得自己渺小和一无是处。</p>
<h3 id="17">17</h3>
<p>事情到了这个地步，还有什么不能说？！当然有，因为能不能说的标准不是淫荡和尊严。不能说的是担心影响别人目前的正常生活，不能说的是不能亵渎我们曾经真诚的爱情。不能说的是为了遵守当时我们的约定。当然，从我这样的顶级禽兽嘴里说出爱情这两个字多少有点尴尬。不过用不着害怕。</p>
<p>说完上海我们来说北京。上文说了我讨厌上海，同样我也不喜欢北京。上文还说了我到过的第一个大城市是上海，很巧，第二个大城市是北京，那是 1987年夏天。1998年我第二次去北京，从此每年至少去一次。今年或许是个例外，因为到目前为止，我还没看出有什么去北京的必要。还有一个多月伟大的 2008年就要过去了，会有转机么？</p>
<p>某年十一月的某个周末，应某大牌唱片公司邀请，我和我的经纪人去北京谈合作的可能。这个可能最后变成了不可能。否则，我在这里码字暴隐私将会是违约行为，受到经济的制裁。当然不能说当时终止谈判是为了今天能一泻千里的发泄自曝。</p>
<p>那次在北京，我被安排住在某高级酒店。某天半夜K来找我，我用她带来的安全套成功射了精，同样成功的确认了她的F罩杯的传说。然后在我睡着的时候 K悄悄的走了。负责任的说，我和K是好朋友，虽然我们交往的时间并不长。我欣赏K的聪慧，我欣赏K的大气，那种男人才有的豁达大气。我相信K是喜欢我的，同样我也知道对她我只有朋友的好感，而无男女的杂念。</p>
<p>后来我和K绝交了，同时也和L绝交了。我同时认识了K和L，她们是好姐妹。我们三人在南锣鼓巷文艺的喝过茶，伴随着K的走光。那晚我发短信勾引L 未遂。后来莫名其妙的我和L接吻抚摸身体。我相信她们不知道我分别和她们的事情。只是当K和L一左一右的时候我会崩溃的歇斯底里，这种感觉就像突然有一天一个男人来到你家，自称是您亲生父亲，边上站着您抽烟沉默的养父。</p>
<h3 id="21">21</h3>
<p>我的很多朋友知道O。聪明一点的知道我们的事情，笨一点的知道我们有事情。有天晚上O喝多了去找我，被我当时的女朋友一眼看穿。这种在电视剧里屡见不鲜的镜头真的发生在自己身上时，经历过大风大浪的李逼还真是有点不知所措诶。感谢我的媒体朋友为我开路当道，《南京零距离》、《直播南京》和《扬子晚报》都没有报道此事。</p>
<p>现在，我决定先无耻的鄙视下我的老朋友吴兄和潮红姐再开始讲和O的事情。这种鄙视以娜姐的气概+十三月果儿的哀怨+此刻办公室的死气沉沉都无法尽兴。鄙视的原因是：在深思熟虑之后，老子已经放弃了和他们一起出去哈皮的想法，但一早他们居然把车开到老子门口强行拉老子起床给老子穿衣服拖老子上车！这种鄙视还由于那天早上电影般的意外+那天晚上的演出是我近五年里最大的激爽！我坐在车上，又是明媚的阳光，又是朦胧但激动的脸，又是高速公路，又是卡拉 OK相声才艺大比拼。这是一个好剧本。</p>
<p>李逼生平唯一一次pogo奉献给了伟大的舌头乐队在杭州的现场。两年后吴吞先生坐在我家沙发上看着我的时候，我依然像两年前那样尊敬他。在我看来，舌头乐队代表了中国最广大摇滚乐爱好者的根本利益，代表中国最先进地下音乐文化的前进方向，代表中国最先进摇滚生产力的发展方向。什么新老教父华语朋克教父民谣天后飞得更高三杰四傻都他妈扯淡，只有舌头才配得上旗帜和封号。唯一遗憾的是我喜欢和尊敬的前吉他手朱小龙先生那天不在场。</p>
<p>在那个气场下我对O一见如故。千辛万苦回到南京后我<strong>似的茶饭不思辗转反侧。起初O对我爱理不理，直到她看了我们的演出又恢复了联系。然后我频频在夜晚跑到她家，最后在某酒店开房</strong>。那晚我料事如神的女人不停的电话轰炸我，纠缠万分脑子空白中我坚持射完才回去，看到她洗漱干净在被窝里凄凄怜怜，铁石心肠的我在洗手间抹了两滴眼泪用六神超能肥皂一个劲的搓**像自摸时激动的把牌捏的又硬又红。</p>
<p>O敲我门那晚我和我女人进行了一场没有拳头和脏话的大战。第二天一早她悄悄的收拾东西拂袖而去，看着空空的房间我想起她看到我和J的短信后离去的场景。我把一切都看的清清楚楚，连<strong>时都清清楚楚，但事情就这么重复着发生，悲剧就这么重复着发生。我还需要解释么？我还需要谎言么？我只不过是一条</strong>长在脸色的野狗罢了。直到离开南京，我再也没敢碰过我女人，哪怕她气愤的爬上我的身体，哪怕她没有尊严的说她一切都不介意。我没了信心。她越是原谅我就越是难过，她越是装作什么都没发生我越是无法面对。我不能说我忏悔，实际上对于O的事情我从来也没有后悔。我只是想一个人呆着。我只是不想说话。</p>
<h3 id="23">23</h3>
<p>今天真是好日子。今天是鄙公司的生日，今天居然还是伟大的蔡司的生日。于是刚才到家第一件事就是抢在十二点之间，边拉屎边给蔡司发短信祝他生日快乐早生贵子。说蔡司是一个伟大的人，不是因为他做海报联系演出拍照片，他的伟大是因为无意中帮我搞过一次情况。对不起了蔡司，一不小心让伟大的您为虎作伥了。</p>
<p>来成都一年多，我大约去过十几次小酒馆，但基本上不是看演出，有时是路过有时是演出和帮别人演出有时外地朋友来访随便找个地方坐坐罢了。李逼一介禽兽，但唐姐等却礼戴有佳让人诚惶诚恐心感温暖。我曾经发誓不和成都的女人发生关系，不和小酒馆的女人发生关系。但是，如您所知，李逼的誓言长期以来一直就是放屁。诶，惭愧惭愧啊，还是先说说小酒馆R吧，我想看到“小酒馆R”这三个字，草爷和蔡司都会<strong>顿起翻江倒海试图对号入座，不过，我诚挚的奉劝还是不要人肉的为好，因为伤了你们的脑细胞是小事，伤了你们的智商就尴尬了——李逼以他的</strong>担保，你们绝对人肉不出来R。</p>
<p>在和R云雨之前我没想到她是这样的情况。她让我想到了F，F是谁？请自行上文搜索。真正苦命的人看起来都不像苦命的，优越的人看起来却一定很优越。就算你骂我郭沫若我还是要说：对R我感到很后悔，我不应该有欲望，我应该做她的大哥，带领她在通往智慧和知识的道路上意气奋发。可事情已经发生了，**不能反射人生不能假设。我能做的就是避免再次发生和再次相遇。</p>
<p>我没有把R带回我家，我们去了宾馆。我用吹风机帮她吹头发，她笑起来特别好看。第二天我带她吃饭然后各回各家。还有一次我和一群朋友在芳草街吃串串，她说没地方去，我就又带她去了宾馆。我发誓，一共就这么两次。</p>
<p>和前面一样我不写细节。我也不会说蔡司是如何不小心助纣为虐的。这是蔡司的事情，让让蔡司去想吧。</p>
<p>今天是个好日子。</p>
<h3 id="24">24</h3>
<p>2007年6月26日下午6点李逼第四次抵达成都。距离上次来蓉已经有6年时光了，6年里李逼在成都的朋友们走的走留的留，6年里李逼对成都的记忆渐渐只剩下建设北路的番茄鱼和昭觉寺的厕所。飞机缓缓降落，李逼透过轩窗，像jin-涛般深情的望着巴蜀大地。日他仙人，外面的景色竟然和李逼未来的生活一样陌生。</p>
<p>李逼的兄弟们在机场做了个简短的欢迎仪式，他说了一段关于开始新生活的豪迈发言，然后吃了个隆重的饭，隆重的去了某知名会所。这章我们就说说李逼的会所生活。</p>
<p>话说十年前的一天，李逼的兄弟小王神秘的带李逼们去一个刚发现的牛逼的地方。洗澡10块不限时，按摩10块一小时。正当李逼躺在那个狭小的木板床上遐想这有什么牛逼的时候，一个袒胸露r的女人推开了门，当时李逼的小JJ就站了起来。她笑着一语双关的说：“小兄弟你这反应也太大了吧，待会可别弄脏了床单哦”。李逼低头鄙视的看着没见过市面的裆下，小脸顿时红的和桃花一般惨烈。随后她让他趴下身子，从背部开始按摩。虽然在这之前李逼已经和自己的右手发生了超友谊关系，但当女人的双手第一次放在李逼c女般娇嫩的臀部上时，可怜的李逼像马小军在于北蓓床上那么哼唧了一声，没出息的she了。</p>
<p>这就是李逼第一次伪会所生活——虽然连她长什么样都没看清楚。随后的一个星期里，李逼对自己异常鄙视。走在街上总觉得大家都认识他，都知道他很不好的去了会所。每天晚上李逼忧伤的躲在被窝里不厌其烦的检查自己的生z器，用放大镜看有没有长出小红疙瘩，直到它如往常一样健康快乐悬着的心才放了下来。从此李逼和他兄弟们幸福的的录像厅生活一去不复返。</p>
<p>有一次，李逼等七人潇洒完之后发现谁也没带银子，只能硬着头皮打电话给一个女同学求助。据我所知，这笔**账到现在也没还。还有一次，李逼们用小冯的三千块学费在一个星期里全部献给了蓬勃的第三产业。那些年，李逼没有银子和女人，跟着兄弟们从东城到西城，赤橙黄绿青蓝紫，什么颜色的桶都玩了个遍。后来他有了银子，想回报于兄弟时，兄弟们都玩不动了，只能打着哈气打麻将。</p>
<p>有一次李逼和他的朋友花了120块钱从沙坪坝建材市场带回一个姑娘，三人轮流玩了一夜。有一次在宾馆，兄弟帮李逼叫了两个姑娘，李逼让她们做数学题，谁分数高谁留下，被兄弟得知后大骂他禽兽。有一次李逼去了东莞，被资本主义的腐朽生活彻底击垮一个星期没缓过来。有一次李逼带着潘绥铭教授的《存在与荒谬》把那个姑娘问哭了。有一次，兄弟从阿姆斯特丹打来电话说这里才是真正的资本主义，李逼像第一次一样哼唧了一生，说他还是更想去东莞。</p>
<h3 id="25">25</h3>
<p>当华尔街数以万计的投资家忙着借用纷繁复杂的数学模型精确计算未来的投资风险与收益时，黎巴嫩籍美国投资家纳西姆.塔勒布却构造了一项十分奇特的投资组合：大量买入行权价格很低，看似毫无价值的认沽权证，用一种十分独特的方式做空美国股市。大家都知道，只有在发生市场预期之外的重大灾难时，塔勒布手中的权证才能有价值。</p>
<p>一位数学分析学大师听了塔勒布的投资组合后，大为吃惊的说：“除非有一架飞机撞进我们的办公大楼，否则你的投资就是慢性自杀。”很不幸，这位大师的办公楼叫纽约世界贸易中心。</p>
<p>911让包括证券市场在内的美国经济遭受重创，而塔勒布和他的投资基金公司却取得了惊人的收益。无独有偶，此次美国次贷危机爆发之前，这位精明的投资家又一次先知先觉，重仓做空，在别人都丢盔弃甲逃之夭夭的时候，他不仅躲过一劫，而且又大赚一笔。</p>
<p>塔勒布先生喜欢讲黑天鹅的故事：在发现澳大利亚黑天鹅之前，欧洲人认为所有的天鹅都是白色的，“黑天鹅”是他们谈论社会和生活的一个约定俗成的惯用语，是指那些不可能存在的事物和不可能发生的事情。但是，信念在第一只黑天鹅出现时就立刻土崩瓦解了。而这个时候，人们认识黑天鹅的视野才刚刚打开。塔勒布先生的这本书叫做《黑天鹅：如何应对不可预知的未来》。</p>
<p>从泰坦尼克号沉没到印度洋海啸，从亚洲金融风暴到汶川地震，从624暂停减持国有股到530夜半鸡叫。无论自然界还是社会领域，无论商业经济还是个人生活，黑天鹅这样的小概率事件几乎无所不在并且摧枯拉朽的改变了我们的生活。别说你我这些凡夫俗子，甚至包括那些成就卓越的大师们都对黑天鹅视而不见，并且自以为以他们掌握的知识和经验可以给出完美的预算。什么“波浪理论”、“周期理论”、“风险价值模型”……得了得了，在塔勒布先生看来，这些想法无异于建造一台合法的印钞机，源源不断的赚取利益。可是，这样一台印钞机和永动机有什么区别呢？我们生活的整个世界，它不是依靠某种确定性得以建立，恰恰相反，它是少数黑天鹅的积累结果。</p>
<p>如果人生是一场旅行，那么在路上遇到一位聊得来的还不算丑的姑娘，甚至有幸和她春宵一夜，这就是黑天鹅。在中国的非主流音乐圈，有多少民谣大师吉他手鼓手被这样的黑天鹅带走，放弃了自己高人一等的音乐天赋呢？。李逼没有放弃，因为他没有大才只有浅薄，他只是深沉的坐在S对面，忧郁的看着车外黑漆漆的田野，实际上只有他自己知道忧郁的背后是在考虑如何下手。</p>
<p>在李逼几十次的游山玩水中，这是很普通的一次——如果没有S。这次，李逼和一个陌生的**坐在一边，S和她的同事坐在另一边。**从上车帮她们放行李开始就极力表现。从三国到中南海从测试版cpu到像叶子一样飞口若悬河吐沫星四射不带标点符号，他妈的简直就是行道不深时期的李逼啊。突然S说：我真喜欢xxx的歌。李逼轻描淡写的回应了一句“哦，xxx，他是我兄弟。”</p>
<p>半个月后S给李逼寄来一张机票，李逼向他的兄弟借了二百块钱。其中50充手机，50给机场建设费，25坐机场大巴，在深夜抵达了S市。在这座陌生的城市里，李逼足不出户呆了两天，S一早出门上班留下早饭，晚上很晚下班带回晚饭。他们顶着S大姨妈的汹涌抗议不顾一切的闯了几次红灯。而后李逼坐着火车况且况且的回到南京，黑天鹅飞不起来了。</p>
<p>还有一只纯洁的黑天鹅在十年前的西双版纳，还有一只**的黑天鹅在中原腹地，还有一只只可远观不可亵玩的黑天鹅在伊利草原。没有一只在未来。</p>
<p>注：本章部分内容节选自张跣《黑天鹅也许更美丽》</p>
<h3 id="26">26</h3>
<p>我知道有一天你会看到这些。<br>
我知道你会很伤心。<br>
在那些日子里你给予我的一切我永生难忘。<br>
而时间已经过去很久了。<br>
我们发过誓：把事情烂在肚子里。<br>
现在，阳光爬上来了城市的大楼，我想起了你。<br>
心儿真的都快碎了。<br>
我还能再给你唱一首歌吗。<br>
你给我的琴弦已经一直没锈。<br>
等你死后我会去海边。<br>
等我死后故事才真正结束。</p>
<p>我知道很快你也会看到这些。<br>
我知道你也会很伤心。<br>
那些飞在天上的日子我是多么幸福。<br>
那碗热腾腾的砂锅馄饨多么让人难忘。<br>
我已经开始自己看大盘了。<br>
我已经住的离草堂很近了。<br>
可是，我又迷失了。<br>
我把最干净的生活给了你。<br>
我把最期盼的婚姻给了你。<br>
而这一些，都成了故事。</p>
<p>现在我真想出去走走<br>
在阳光下掏个耳朵，还有一杯竹叶青<br>
看着斑驳的树叶一片片落下<br>
看着人们一个个老去<br>
现在我真想唱一首歌<br>
名字叫做《将进酒》</p>
<h3 id="27">27</h3>
<p>这个行业有潜规则吗，肯定是有的。有人就有中国人，有中国人就有关系，有关系就有规则，有规则就有潜规则。您觉得我这个推理怎么样。喔？不怎么样。这就对了！因为李逼也不觉得怎么样，纯粹是为赋新词强说愁。我喜欢刚正不阿的精神，我喜欢是非分明的态度。所以李逼没有潜规则。从排队买票到演出顺序，李逼非但不利用关系，甚至为了避嫌还故意挑坏时段。这样的好处是：演不好有借口，演好了更牛逼。同时还可以对无处不在的关系户用“*<strong>，瞅你丫那操性，和你丫死磕”等</strong>词汇强烈谴责。每次侥幸得逞之后我在内心总是对自己说：李逼，***怎么可以这么冰雪聪明！</p>
<p>前天一个朋友急切的告诉我她的巨大发现。这个发现是：我的一个知名好朋友和我的另一个知名好朋友存在亲密接触的概率很大。一看到这个命题我顿时就激动了，饶有兴致的听她分析两个好朋友的博客，在“洱海”，“指尖”等词语中寻找蛛丝马迹，很遗憾，是否接触到**的地步我们无法确认。不过接触几乎是肯定的了。八卦有魅力，我爱陈冠希。这个事情我会继续观察下去，并且下次有机会三人碰头时再仔细偷窥。这是一个伟大的事业，虽然我要猥琐着去办。</p>
<p>我的正牌经纪人是大腕，我的替补经纪人也是大腕。她们是女性，她们白求恩般的奉献精神帮我做成了一系列事情，比如大牌唱片公司请我们飞过去谈事情诶，比如广深小巡演我们居然只亏了一千块钱诶——这太他妈让人震惊了。但是我们之间没有潜规则，这个我愿意用任何东西发誓。</p>
<p>以G小姐，N小姐，Y小姐为代表的圈内达人也没和我有潜规则。至于她们有没有潜规则我的意愿，你可以问她们，问到了别忘了悄悄的告诉我哦。草率的说一句，北京圈内的乐手歌手记者经纪人等相关行业相关人士都和我没有身体接触。南京圈内的乐手歌手以及他们的家属和我也没有身体接触。我在南京玩的一帮主要朋友，如潮红姐朋克张毛毛白哥以及他们的父母子孙都和我没身体接触。我想这些会让你们遗憾。但我却为此感到些许自豪。</p>
<p>总的来说，这个章节是澄清。因为写的过程中无数人问我和xx（一般是熟人或知名人士）有没有过一腿。也有少数好恶份子问我xx搞起来怎么样。我澄清这些不是为她们的品行做担保，而是为她们没有和我有关系发誓。同时，也给这些人的男女朋友亲戚姐妹吃个定心丸，她们没有被禽兽李糟蹋过，这是多么出淤泥而不染的事情啊。</p>
<h3 id="28">28</h3>
<p>今年上半年我经历人生低潮的时候，曾经花了一个星期时间废寝忘食的写过一本回忆录。这里面是我三十年的所见所遇所想，都是真姓名真地点真时间。我把他写下来是觉得自己快不行了，我想死后留给我最爱的侄子，等他长大了就会明白叔叔是怎样一个人。</p>
<p>上周日那个阳光明媚的上午，我不知道哪根筋短路了决定重写现在你们看到的这篇。不同的是内容和手法，相同的是和以前一样迅速写完。写作有时就像抽烟，必须一根接一根的快，必须的。好了，现在写完了。我不知道下面该怎么办。</p>
<p>很遗憾我没有用完二十六个字母。同时如果你仔细观看，会发现李逼从来没交代从“你好”到“我们搞一下吧”这之间漫长的经过。这个过程才是最肮脏最装逼最虚伪也最失败的李逼。请放心，老天爷看的清清楚楚，老天爷有自己的惩罚手段。</p>
<p>不要问我写作时是什么心情，如果你也有过往事就像电影一帧一帧划过的经历，那么你就该知道我做的只不过是快速而准确的记录。作为一个聪明人我知道我比那些人牛逼，我也知道比偶像差的太远。虽然在写作的这几天里你们的翻页高潮刺激我必须写的更快更高更强，但总的来说炫耀不是此文的动机，所以恭维和辱骂也不是我想要的结果。总之，要是下次有机会看我们演出，您想笑就笑想哭就哭，骂**还是装逼悉听尊便。每个人看完都会有每个人的想法。但我最希望的是：看完后你能看看自己和眼前的这个世界。</p>
<p>如果我的希望达成，那么我们一起来感谢：<br>
感谢娜姐，她的大无畏精神刺激了我。<br>
感谢征服妹妹，是她把我拉进了伟大的月亮组。<br>
感谢爵爷草爷彼得唐僧等人，你们的上蹿下跳强强联手消灭了影响月亮组伟大气质的**帖子的嚣张气焰。<br>
感谢为IT事业的发展作出巨大贡献的先人，没有他们，你们享受不到直播的痛快。<br>
感谢红梅和绿茶，在写作的过程中他们一直陪伴着我。<br>
感谢伟大的音乐家，没有声音的刺激怎么能写出刺激的文章呢？</p>
<p>三十岁生日那天是我这次生病最严重的一天，我躺在床上，两眼汪汪，周围没有一个人，家乡遥不可及，青春即将散场。我强忍着咳嗽着爬起来在笔记本上写下一行字：三十岁以前的人生是一瓢黄河水，三十岁以后的人生是一盒三鹿奶。</p>
<p>用这句话作为结尾你觉得怎么样？<br>
再见吧。</p>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[JavaScript中的函数]]></title>
        <id>https://merpyzf.github.io/post/javascript-zhong-de-han-shu/</id>
        <link href="https://merpyzf.github.io/post/javascript-zhong-de-han-shu/">
        </link>
        <updated>2020-05-18T01:43:27.000Z</updated>
        <content type="html"><![CDATA[<h3 id="函数的定义方式">函数的定义方式</h3>
<h4 id="函数声明方式命名函数">函数声明方式（命名函数）</h4>
<pre><code>function fn(){};
</code></pre>
<h4 id="函数表达式匿名函数">函数表达式（匿名函数）</h4>
<pre><code>var fun = function(){};
</code></pre>
<h4 id="new-function">new Function()</h4>
<pre><code>var fun = new Function('a', 'b','console.log(a + b)');
fun(1,2) //3
</code></pre>
<h3 id="函数内this的指向">函数内this的指向</h3>
<p>这些this的指向，是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同，一般指向我们的调用者。</p>
<table>
<thead>
<tr>
<th>一个普通标题</th>
<th>一个普通标题</th>
</tr>
</thead>
<tbody>
<tr>
<td>普通函数调用</td>
<td>window</td>
</tr>
<tr>
<td>构造函数调用</td>
<td>实例对象</td>
</tr>
<tr>
<td>对象方法调用</td>
<td>该方法所属对象</td>
</tr>
<tr>
<td>事件绑定方法</td>
<td>绑定事件对象</td>
</tr>
<tr>
<td>定时器函数</td>
<td>window</td>
</tr>
<tr>
<td>立即执行函数</td>
<td>window</td>
</tr>
</tbody>
</table>
<h3 id="几种改变函数内this指向的方式">几种改变函数内this指向的方式</h3>
<h4 id="call">call</h4>
<h4 id="apply">apply</h4>
<h4 id="bind">bind</h4>
<h3 id="高阶函数">高阶函数</h3>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[JavaScript的面向对象]]></title>
        <id>https://merpyzf.github.io/post/javascript-de-mian-xiang-dui-xiang/</id>
        <link href="https://merpyzf.github.io/post/javascript-de-mian-xiang-dui-xiang/">
        </link>
        <updated>2020-05-15T15:53:48.000Z</updated>
        <content type="html"><![CDATA[<h3 id="概述">概述</h3>
<p>在典型的OOP语言中（如JAVA），都存在类的概念，类是对象的模版，对象是类的实例。当在ES6之前，JS并没有引入类的概念。<br>
在ES6之前，对象不是基于类创建的，而是用一种成为__构建函数__的特殊函数来定义对象和它们的特征。</p>
<h3 id="创建对象的三种方式">创建对象的三种方式</h3>
<h4 id="对象字面量无法复用">对象字面量（无法复用）</h4>
<pre><code>var obj = {};
</code></pre>
<h4 id="new-object无法复用">new Object（无法复用）</h4>
<pre><code>var obj = new Object();
</code></pre>
<h4 id="自定义构造函数">自定义构造函数</h4>
<pre><code>    function Star(name, age) {
        this.name = name;
        this.age = age;
        this.sing = function () {
            console.log('我会唱歌');
        }
    }
    let ldh = new Star('刘德华', 18);
    ldh.sing();
    let zxy = new Star('张学友', 20);
    zxy.sing();
</code></pre>
<p>__构成函数__是一种特殊的函数，主要用来初始化对象，即为对象成员变量赋初始值，它总与new一起使用。我们可以把对象总一些公共的属性和方法抽取出来，然后封装到这个函数里面。</p>
<p><strong>通过对构造函数执行new命令时会做的四件事情：</strong></p>
<ol>
<li>在内存总创建一个新的空对象。</li>
<li>让this指向这个新对象。</li>
<li>执行构造函数里的代码，给这个新对象添加属性和方法。</li>
<li>返回这个对象（只是构造函数里面不需要写return）。</li>
</ol>
<p><strong>静态成员和实例成员</strong>:</p>
<ol>
<li>静态成员：在构造函数上添加的成员称为静态成员。只能由构造函数本身来访问。</li>
</ol>
<pre><code>  function Star(name, age) {
     this.name = name;
     this.age = age;
     this.sing = function () {
         console.log('我会唱歌');
     }
 }
 let ldh = new Star('刘德华', 18);
 // 创建一个变量名为gender的静态成员
 Star.gender = '男';
 console.log(Star.gender); // 男
 console.log(ldh.gender); // undefined
</code></pre>
<ol start="2">
<li>实例成员：在构造函数内部创建的对象成员称为实例成员，只能通过实例化的对象来访问。</li>
</ol>
<p><strong>自定义构造函数创建对象的问题</strong></p>
<p>构造函数方法虽然好用，但是存在浪费内存空间的问题。对于通过同一个构造函数创建出的实例对象，其中的复杂数据类型都会再开辟一块内存空间来存放，而不会复用。通过使用构造函数原型prototype即可解决以上问题。<br>
<img src="https://merpyzf.github.io/post-images/1589613097429.png" alt="" loading="lazy"></p>
<h3 id="构造函数原型prototype">构造函数原型prototype</h3>
<p>构造函数通过原型分配的函数是对所有对象__共享的__(内存复用)。<br>
JavaScript规定，每一个构造函数都有一个prototype属性，指向另一个对象。这个对象总的所有的属性和方法，都会被构造函数说拥有。<br>
我们可以把哪些不变的方法，直接定义在prototype对象上，这样所有的实例对象就可以共享这些方法了。</p>
<pre><code>  function Star(name, age) {
        this.name = name;
        this.age = age;
        // this.sing = function () {
        //     console.log('我会唱歌');
        // }
    }
    // prototype是函数才会有的属性
    // 向Star构造函数的原型对象中添加方法
    Star.prototype.sing = function(){
        console.log('我会唱歌');
    }
    let ldh = new Star('刘德华', 18);
    ldh.sing();
    let zxy = new Star('张学友', 20);
    zxy.sing();
    console.log(ldh.sing === zxy.sing) // true
</code></pre>
<h3 id="对象原型-__proto__">对象原型 <code>__proto__</code></h3>
<p>对象都会有一个属性<code>__proto__</code>指向构造函数的prototype原型对象，之所以我们对象可以使用构造函数prototype原型对象的属性和方法，就是因为对象有<code>__proto__</code> 原型的存在。</p>
<pre><code>   function Star(name, age) {
        this.name = name;
        this.age = age;
        this.sing = function () {
            console.log('wowowo我会唱歌');
        }
    }
    // 向Star构造函数的原型对象中添加方法
    Star.prototype.sing = function(){
        console.log('我会唱歌');
    }
    let ldh = new Star('刘德华', 18);
    ldh.sing(); // wowowo我会唱
    console.log(ldh.__proto__ === Star.prototype); // true
</code></pre>
<p>实例对象方法的查找规则：首先会先看当前实例对象的内部是否存在xx方法，如果有就去执行这个对象上的xx方法。如果对象上没有定义这个方法，因为实例对象上有<code>__proto__</code>的存在，就去构造函数的prototype对象中查找xx方法。<br>
<img src="https://merpyzf.github.io/post-images/1589626869955.png" alt="" loading="lazy"></p>
<ul>
<li><code>__proto__</code>对象原型和原型对象prototype是等价的。</li>
<li><code>__proto__</code>对象原型的意义就在于为对象的查找机制提供了一个方向，或者说一条路线。但是它是一个非标准的属性，因此实际开发中，不可以使用这个属性，它只是内部指向原型对象prototype。</li>
</ul>
<h3 id="contructor-构造函数">contructor 构造函数</h3>
<p>对象原型（ <code>__proto__</code>）和构造函数（<code>prototype</code>）原型对象里面都有一个consgructor的属性，constructor我们称之为构造函数，因为它指回构造函数本身。<br>
constructor主要用于记录该对象应用于哪个构造函数，它可以让原型对象重新指向原来的构造函数。<br>
__(很多情况下，我们需要手动利用constructor)__这个属性指回原来的构造函数。</p>
<pre><code>    function Star(name, age) {
        this.name = name;
        this.age = age;
    }
    Star.prototype = {
        construct: Star,
        sing: function () {
            console.log('我会唱歌儿');
        },
        movie: function () {
            console.log('我会拍电影');
        }
    }
    let ldh = new Star('刘德华', 18);
    let zxy = new Star('张学友', 20);
    console.log(Star.prototype)
    ldh.sing();
    zxy.movie();
</code></pre>
<p>当一个函数被创建时，它的prototype属性也被创建，且该原型对象的construct属性指向该函数，当使用对象字面量形式改写原型对象Star.prototype时，则该constructor指向的是Object，为了避免这一点，需要手动改写原型对象。即通过手动设置construct的属性。</p>
<h3 id="构造函数-实例-原型对象prototype三者之间的关系">构造函数、实例、原型对象(prototype)三者之间的关系</h3>
<figure data-type="image" tabindex="1"><img src="https://merpyzf.github.io/post-images/1589633858009.png" alt="" loading="lazy"></figure>
<h3 id="原型链">原型链</h3>
<p><img src="https://merpyzf.github.io/post-images/1589634276261.png" alt="" loading="lazy"><br>
JavaScript的成员查找机制：</p>
<ol>
<li>当访问一个对象的属性或方法时，首先查找这个__对象自身__中属否存在该属性。</li>
<li>如果没有就查找它的原型（也就是实例对象<code>__proto__</code>指向的__prototype原型对象__）。</li>
<li>如果依旧没有找到就继续去向上查找原型对象的原型（<strong>Object的原型对象</strong>）。</li>
<li>以此类推一直找到Object为止（<strong>null</strong>）。</li>
</ol>
<h3 id="原型对象中this指向">原型对象中this指向</h3>
<pre><code>    function Star(name, age) {
        // 在构造函数中的this指向的是对象实例
        this.name = name;
        this.age = age;
    }
    let that;
    // Star构造函数的原型对象
    Star.prototype.sing = function () {
        that = this;
        //this指向最终的调用对象
        console.log('我会唱歌');
    }
    var ldh = new Star('刘德华', 18);
    console.log(ldh.sing());
    console.log(that);
</code></pre>
<ol>
<li>在构造函数中，里面this指向的是实例对象。</li>
<li>原型对象函数里的this，指向的是最终调用该函数的实例对象。</li>
</ol>
<h3 id="扩展内置对象的方法">扩展内置对象的方法</h3>
<pre><code>    // 通过构造函数的原型对象扩展原有的功能
    Array.prototype.sum = function () {
        let sum = 0;
        for (let i = 0; i &lt; this.length; i++) {
            sum += this[i];
        }
        return sum;
    }
    // 不允许采用这种方式书写
    // Array.prototype = {
    //     constructor: Array,
    //     sum: function () {
    //         let sum = 0;
    //         for (let i = 0; i &lt; this.length; i++) {
    //             sum += this[i];
    //         }
    //         return sum;
    //     }
    // }
    let nums = [1, 2, 3, 4];
    console.log(nums.sum());
</code></pre>
<h3 id="继承">继承</h3>
<p>ES6之前没有提供extends继承。我们可以通过<code>构造函数+原型对象</code>模拟实现继承，这种方式被称为组合继承。</p>
<h4 id="call">call</h4>
<p>调用这个函数，并自定义函数运行时的this指向</p>
<pre><code>func.call(thisArg, arg1, arg2, ...)
</code></pre>
<ul>
<li>thsiArg: 当前调用函数的this所要指向的对象。</li>
<li>arg1，arg2: 向函数中传递的参数。</li>
</ul>
<h4 id="借用父构造函数继承属性">借用父构造函数继承属性</h4>
<pre><code>   // 1. 父构造函数
    function Father(uname, age){
        this.uname = uname;
        this.age = age;
    }

    // 2. 子构造函数
    function Son(uname, age, school) {
        this.school = school;
        // 当通过call方法调用Father构造函数的时候，运行时，Father中的this指向的是son，那么对uname和age的赋值就是作用在son上的。
        Father.call(this, uname, age);
    }

    let son = new Son('刘德华', 18, &quot;不知道哦&quot;);
    console.log(son.uname);
    console.log(son.age);
    console.log(son.school);
</code></pre>
<h4 id="真的是继承么">真的是继承么？</h4>
<p>继承意味着复制，然而JavaScript默认不会复制对象的属性，相反，JavaScript只是在两个对象之间创建了一个关联，这样，一个对象就可以通过委托访问另一个对象的属性和函数，所以与其叫继承不如说是委托准确些。</p>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[ES6中的函数]]></title>
        <id>https://merpyzf.github.io/post/es6-zhong-de-han-shu/</id>
        <link href="https://merpyzf.github.io/post/es6-zhong-de-han-shu/">
        </link>
        <updated>2020-05-13T08:17:25.000Z</updated>
        <content type="html"><![CDATA[<h3 id="函数参数的默认值">函数参数的默认值</h3>
<p>ES6允许为函数的参数设置默认值，即直接写在参数定义的后面。</p>
<pre><code>function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
</code></pre>
<p>参数的默认值也可以是一个表达式。参数默认值不是传值的，而是每次都重新计算默认值表达式的值。</p>
<pre><code>let x = 99;
function foo(p = x + 1) {
  console.log(p);
}
foo() // 100

x = 100;
foo() // 101
</code></pre>
<h3 id="与解构赋值默认值结合使用">与解构赋值默认值结合使用</h3>
<p>参数默认值可以与结构赋值的默认值，结合起来使用。</p>
<pre><code>function foo({x, y = 5}) {
  console.log(x, y);
}

foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
</code></pre>
<p>上面的代码只使用了对象的解构赋值默认值，没有使用函数参数的默认值。只有当函数foo的参数是一个对象时，变量x和y才会通过解构赋值生成。如果函数foo调用时没有提供参数，者变量x和y就不会生成，从而报错。通过提供函数参数的默认值，就可以避免这种情况。</p>
<pre><code>function foo({x, y = 5} = {}) {
  console.log(x, y);
}
// 解构赋值的默认值
foo() // undefined 5
</code></pre>
<p>只有当函数的参数是一个对象时，变量的x和y才会通过解构赋值生成，因此提供一个空对象作为参数的默认值才可以确保x和y可以生成。</p>
<h3 id="参数默认值的位置">参数默认值的位置</h3>
<p>通常情况下，定义了默认值的参数，应该是函数的尾参数。这样比较容易看出来，到底省略了哪些参数，<strong>如果非尾部的参数设置默认值，实际上这个参数是没有办法省略的</strong>。</p>
<pre><code>// 例一
function f(x = 1, y) {
  return [x, y];
}

f() // [1, undefined]
f(2) // [2, undefined]
f(, 1) // 报错
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]
</code></pre>
<p>上面的代码中，有默认值的参数都不是尾参数。若想使用参数的默认值只能通过显式的输入<code>undefined</code>。当传入<code>undefined</code>时将触发该参数等于默认值，<strong>null则没有这个效果。</strong></p>
<pre><code>function foo(x = 5, y = 6) {
  console.log(x, y);
}

foo(undefined, null)
// 5 null
</code></pre>
<h3 id="函数的length属性">函数的length属性</h3>
<p>制定了默认值以后，函数的<code>length</code>属性，将返回没有指定默认值的参数的个数。</p>
<pre><code>(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
</code></pre>
<p><code>length</code>属性的含义是该函数预期传入的参数个数。某个参数指定默认值以后，预期传入的参数个数就不包括这个参数了。同理，rest参数也不会计入<code>length</code>属性。</p>
<pre><code>(function(...args) {}).length // 0
</code></pre>
<p><strong>如果设置了默认值的参数不是尾参数，那么length属性也不再计入后面的参数了。</strong></p>
<pre><code>(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
</code></pre>
<h3 id="rest参数">rest参数</h3>
<p>ES6 引入了 rest 参数 （形式为<code>...变量名</code>），用于获取函数的多余参数，这样就不需要使用<code>arguments</code>对象了。rest 参数搭配的变量是一个数组，该变量将多余的参数放入数组中。</p>
<pre><code>function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10
</code></pre>
<h3 id="name-属性">name 属性</h3>
<p>函数的<code>name</code>属性，返回函数的函数名称。</p>
<pre><code>function foo() {}
foo.name // &quot;foo&quot;
</code></pre>
<p>如果将一个匿名函数赋值给一个变量，ES5 的<code>name</code>属性，会返回空字符串，而 ES6 的<code>name</code>属性会返回实际的函数名。</p>
<pre><code>var f = function () {};

// ES5
f.name // &quot;&quot;

// ES6
f.name // &quot;f&quot;
</code></pre>
<p>如果将一个具名函数赋值给一个变量，则 ES5 和 ES6 的name属性都返回这个具名函数原本的名字。</p>
<pre><code>const bar = function baz() {};

// ES5
bar.name // &quot;baz&quot;

// ES6
bar.name // &quot;baz&quot;
</code></pre>
<h3 id="箭头函数">箭头函数</h3>
<p>ES6 允许使用 <code>=&gt;</code>定义函数。</p>
<pre><code>let f = x =&gt; v;
// 等同于
let f = function(x){
    return v;
}
</code></pre>
<p>注：如果函数只有一个参数，那么可以省略掉括号，如果函数的函数体只有一条返回语句，那么可以省略掉花括号和return。</p>
<p>如果尖头函数不需要参数或需要多个参数，就使用一个圆括号代表参数部分。</p>
<pre><code>let f = () =&gt; 5;
// 等价于
let f = function(){
    return 5;
}

let sum = (num1, num2) =&gt; num1 + num2;
// 等价于
let sum = function(num1, num2){
    return num1+num2
}
</code></pre>
<p>如果箭头函数的代码块部分多于一条语句，就要使用大括号扩起来，并使使用<code>return</code>语句返回。</p>
<pre><code>var sum = (num1, num2) =&gt; {
    let sum = num1 + num2;
    return sum;
}
</code></pre>
<p>由于大括号被解释为代码块，所以如果箭头函数直接返回一个对象，则必须在对象的外面加上一个括号，否则会报错。</p>
<pre><code>  // 直接返回一个对象
   let getTempItem = id =&gt;({id: id, temp: 10});
   console.log(getTempItem(10));
</code></pre>
<p>箭头函数可以与变量解构结合使用。</p>
<pre><code>const full = ({ first, last }) =&gt; first + ' ' + last;
// 等价于
function full(person){
    return person.first + ' '+person.last;
}
</code></pre>
<p>箭头函数可以使得表达更加简洁。</p>
<pre><code>const isEven =  n =&gt; n % 2 === 0;
const square =  n =&gt; n * n; 
</code></pre>
<p>箭头函数可以用来简化回调函数。</p>
<pre><code>// es5函数的写法
[1, 2, 3].map(function(x){
    return x * x;
});

// 箭头函数的写法
[1,2,3].map(x =&gt; x * x);
</code></pre>
<p>排序的写法。</p>
<pre><code>// es5函数写法
let result = values.sort(function(a, b){
    return a - b;
});

// 箭头函数写法
let result = values.sort((a, b) =&gt; a - b );
</code></pre>
<h3 id="箭头函数使用注意点">箭头函数使用注意点</h3>
<ol>
<li><strong>函数体内的<code>this</code>对象，就是定义时所在的对象，而不是使用时所在的对象</strong>。</li>
<li>不可以当作构造函数，也就是说，不可以使用<code>new</code>命令，否则会抛出一个错误。</li>
<li>不可以使用<code>arguments</code>对象，该对象在函数体内不存在。如果要用，可以用rest参数替代。</li>
<li>不可以使用<code>yield</code>命令，因此箭头函数不能用作Generator。</li>
</ol>
<h3 id="关于箭头函数中-this的说明">关于箭头函数中 <code>this</code>的说明</h3>
<p><code>this</code>对象的指向是可变的，但是在箭头函数中，它是固定的。</p>
<pre><code>function foo(){
    setTimeout(()=&gt;{
        console.log('id: ', this.id);
    }, 100);
}
var id = 21;
foo.call({ id: 42 });

// 编译成es5的代码如下：
function foo() {
  var _this = this;

  setTimeout(function () {
    console.log('id:', _this.id);
  });
}

var id = 21;
foo.call({
  id: 42
});
</code></pre>
<p><code>this</code>指向的固化，并不是因为箭头函数内部有绑定<code>this</code>的机制，实际原因是箭头函数根本没有自己的<code>this</code>，导致内部的<code>this</code>就是外层代码块的<code>this</code>。正式因为它没有this，所以也就不能用作构造函数。</p>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[ES6的Module语法]]></title>
        <id>https://merpyzf.github.io/post/es6-de-module-yu-fa/</id>
        <link href="https://merpyzf.github.io/post/es6-de-module-yu-fa/">
        </link>
        <updated>2020-05-13T04:13:54.000Z</updated>
        <content type="html"><![CDATA[<p>巴拉巴拉</p>
]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[JavaScript的模块系统扫盲]]></title>
        <id>https://merpyzf.github.io/post/javascript-de-mo-kuai-xi-tong/</id>
        <link href="https://merpyzf.github.io/post/javascript-de-mo-kuai-xi-tong/">
        </link>
        <updated>2020-05-12T08:05:46.000Z</updated>
        <content type="html"><![CDATA[<h3 id="现状">现状</h3>
<p>伴随着移动互联的大潮，当今越来越多的网站已经从网页模式进化到了 Webapp 模式。它们运行在现代的高级浏览器里，使用 HTML5、 CSS3、 ES6 等更新的技术来开发丰富的功能，网页已经不仅仅是完成浏览的基本需求，并且webapp通常是一个单页面应用，每一个视图通过异步的方式加载，这导致页面初始化和使用过程中会加载越来越多的 JavaScript 代码，这给前端开发的流程和资源组织带来了巨大的挑战。</p>
<p>前端开发和其他开发工作的主要区别，首先是前端是基于多语言、多层次的编码和组织工作，其次前端产品的交付是基于浏览器，这些资源是通过增量加载的方式运行到浏览器端，如何在开发环境组织好这些碎片化的代码和资源，并且保证他们在浏览器端快速、优雅的加载和更新，就需要一个模块化系统，这个理想中的模块化系统是前端工程师多年来一直探索的难题。</p>
<h3 id="已存在的模块系统">已存在的模块系统</h3>
<h4 id="script标签"><script>标签</h4>
<pre><code>&lt;script src=&quot;module1.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;module2.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;libraryA.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;module3.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>这是最原始的 JavaScript 文件加载方式，如果把每一个文件看做是一个模块，那么他们的接口通常是暴露在全局作用域下，也就是定义在 window 对象中，不同模块的接口调用都是一个作用域中，一些复杂的框架，会使用命名空间的概念来组织这些模块的接口，典型的例子如 YUI 库。</p>
<p>这种原始的加载方式暴露了一些显而易见的弊端：</p>
<ul>
<li>全局作用域下容易造成变量冲突。</li>
<li>文件智能按照<code>&lt;script&gt;</code>的书写顺序进行加载。</li>
<li>开发人员必须主观解决模块和代码库的依赖关系。</li>
<li>在大型项目中各种资源难以管理，长期积累的问题导致代码库混乱不堪。</li>
</ul>
<h3 id="commonjs">CommonJS</h3>
<p>服务器端的 Node.js 遵循 CommonJS 规范，该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块，然后通过 exports 或 module.exports 来导出需要暴露的接口。</p>
<pre><code>require(&quot;module&quot;);
require(&quot;../file.js&quot;);
exports.doStuff = function() {};
module.exports = someValue;
</code></pre>
<p>优点：</p>
<ul>
<li>服务端模块便于重用。</li>
<li>NPM中已经有将近20万个可以使用的模块包，生态好。</li>
<li>简单并容易使用。</li>
</ul>
<p>缺点：</p>
<ul>
<li>同步的模块加载不适合在浏览器环境中，同步意味着阻塞加载，浏览器的资源是异步加载的。</li>
<li>不能非阻塞的并行加载多个模块。</li>
</ul>
<p>实现：</p>
<ul>
<li>服务器端的 Node.js</li>
<li>Browserify，浏览器端的 CommonJS 实现，可以使用 NPM 的模块，但是编译打包后的文件体积可能很大</li>
</ul>
<h3 id="amd">AMD</h3>
<p>Asynchronous Module Definition 异步模块定义，规范其实只有一个主要接口<code>define(id?, dependencies?, factory)</code>,它要在声明模块的时候指定所有的依赖<code>dependencies</code>，并且还要当做形参传到 factory 中，对于依赖的模块提前执行，依赖前置。</p>
<pre><code>define(&quot;module&quot;, [&quot;dep1&quot;, &quot;dep2&quot;], function(d1, d2) {
  return someExportedValue;
});
require([&quot;module&quot;, &quot;../file&quot;], function(module, file) { /* ... */ });
</code></pre>
<p>优点：</p>
<ul>
<li>适合在浏览器环境中异步加载模块。</li>
<li>可以并行加载多个模块。</li>
</ul>
<p>缺点：</p>
<ul>
<li>提高了开发成本，代码的阅读和书写比较困难，模块定义方式的语义不顺畅。</li>
<li>不符合通用的模块化思维，是一种妥协的实现。</li>
</ul>
<p>实现：</p>
<ul>
<li>RequireJS</li>
<li>curl</li>
</ul>
]]></content>
    </entry>
</feed>