Images can't contain alpha channels or transparencies

今天给一个已经reject了N多次的APP做再一次的上传和提交。因为一些问题,需要重新上传图片。这算是iTunes Connect更新之后,头一回做图片上传的操作,发现果真方便不少。

首先已有的图片展示速度提升很多,点击图片可以全屏查看,鼠标放图片上会在左上角有个红色的删除按钮。最棒的是上传图片的时候,可以拖进去,而且还是批量的。比老版的点击一次上传一张要方便多了。而且图片上传的速度也是快的惊人。But 图片上传失败了,就像上面那个图片。

stackoverflow上面找到了答案,得使用Photoshop重新生成图片,然后去掉alpha值,也就是透明度。

我的操作流程是这样的:

  • 在Photoshop中打开图片
  • alt+ctrl+shift+s(或者文件=>存储为web所用格式)
  • 去掉透明度复选框的选中
  • 存储

去掉透明度复选框的选中

这样再次生成的图片,就可以顺利的上传到iTunes connect上面了

ecmascript5-defineProperty

在ECMAScript3中,对象的属性是很简单的,可读可写可遍历,也不存在公有私有的说法。

为了实现只读变量,很多时候不得不依赖闭包。


var o = (function(){
    var readOnlyVarible = '我是只读的';
        
    return {
        getReadAbleVarible = function(){
            return readOnlyVarible;
        }
    };
});


在ECMAScript5中,针对对象的属性,新增三种描述writable(可写性),enumerable(可枚举性)和configurable(可配置性),还有一个是跟早期的描述等同的value(属性值)

下面是摘自MDN中关于这四个属性描述

configurable
当且仅当这个属性描述符值为 true 时,该属性可能会改变,也可能会被从相应的对象删除。默认为 false
enumerable
true 当且仅当该属性出现在相应的对象枚举属性中。默认为 false
数据描述符同时具有以下可选键值:
value
与属性相关的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
writable
true 当且仅当可能用 赋值运算符 改变与属性相关的值。默认为 false

上述的默认值是指的用Object.defineProperty()方法创建属性的时候的默认值,而不是通常那种直接量或者.的方式创建的属性的默认值,使用后者创建属性的时候,三个bool型的描述符的值都是true。

有了这新增的三个描述符之后,在创建只读属性的时候就方便多了


var o = {};

Object.defineProperty(o,'readOnlyVarible',{
    writable: false,
    enumberable: true,
    configurable: false, // 防止修改可写性
    value: '我是只读的'
});


或者下面这种方式(把一个已经定义的属性设置为只读的)


var o = {};

o.readOnlyVarible = '我是只读的'

Object.defineProperty(o,'readOnlyVarible',{
    writable: false,
    enumberable: true,
    configurable: false // 防止修改可写性
});


本文是翻译的https://help.github.com/articles/using-pull-requests/ 。旨在帮助大家了解GitHub上面如何给别人的仓库提交变更,英文好的同学可以查看上述网址,获取最新的内容

Pull Request可以让你通知别人,你已经推送了一个修改到GitHub的版本库。在pull request被发送之后,感兴趣的成员可以review这些代码变动,讨论可能需要的修改,甚至在必要的时候在这之后push一些commits

本指南详细描述了从发送一个pull request(假设的),使用各种代码审查工具和管理工具,到最后完成变更的过程。

协同开发模式的快速笔记

在GitHub上面有两种流行的协同开发模式:

Fork & Pull

Fork & Pull模式让任何人都可以fork(复制的意思)一个已经存在的版本库并且提交变更到他们自己fork出来的版本库上,而不需要获得源版本库的访问权限。变更必须通过项目维护者才能放入源版本库。这种模式降低了给新贡献者带来的麻烦,在开源项目非常流行,因为它使人们能够独立工作而不需要前期的协调。

共享版本库模式

共享版本库模式在小团队和组织合作的私人项目中更为普遍。每个人都有push到单一共享版本库或者用来隔离变更的顶级分支的权限。

Pull requests 在 Fork & Pull 模式 中更加有用,因为它提供了一种方法去提醒项目维护者,在他的fork里面有变更. 但是,在共享版本库模式中,他们同样有用,当人们启动代码审查或者在合并到主分支之前讨论所有变更的时候

开始之前

本指南假设您有一个GitHub的帐户 ,你已经Fork了一个的现有版本,并push了您的更改。想要获得关于Fork和推送变更的帮助,请参阅文章——Forking a Repo

启动Pull Request

在下面的例子中,codercat在Fork自Octocat的Spoon-Knife版本库中完成了一些工作,在他的Fork中push了一个commit,并希望有人来审查和合并。

进入到你希望别人Pull变更的版本库中,点击Pull Request按钮。

  1. 切换到您的分支 分支选择下拉
  2. 点击Compare & review按钮 Pull Request 按钮

Pull request可以基于任何分支或者commit发送,但是推荐是从一个顶级分支。这样,在必要的时候,一些跟随的commit可以被push,去更新这个Pull Request。

审查要提交的Pull Request

开始审查之后,你将会进入一个审查页面,在这里你可以概览到所有在你的分支和源版本库的master分支之间的变动。你可以审查在所有commit中的注释,明白哪些文件发生了变动,看到所有在你的分支中的贡献者。
Pull Request 复审页

改变分支范围和目标版本库

默认情况下,Pull Request被认为是基于父版本库的默认分支 。在这种情况下, hubot/Spoon-Knife是contoctocat/Spoon-Knife中Fork出来的。所以这次的Pull Request被假定为基于octocat/Spoon-Knife版本库的master分支。

在绝大多数情况下,默认值将是正确的,但是,如果有任何信息不正确,您可以从下拉列表中更改父版本库和分支。点击顶部的Edit按钮,可以让你换你的头和底座,以及建立各种参考点之间的差别。这里引用可以包括:

  • 添加了tag的release
  • commit的SHA值
  • 分支名称
  • Git的历史标志(如HEAD^1 )
  • 有效的时间引用(如master@{1day} )

欲了解更多信息,请查看our help article on setting up comparisons
Pull Request 选择比较的分支

理解分支范围的最简单的方法是这样的: 基础分支( base branch )是你认为变更应该应用的分支,而头部分支( head branch )是你想被人应用的分支 。

改变基础版本库会导致Pull Request发生时候的通知名单发送变动。所有对基础版本库有push权限的人都会在新的Pull Request产生的时候收到邮件,并且在他们下次登录的时候能够在他们的仪表盘查看该Pull Request。

当您更改分支范围内的任何信息,commit和文件改动的预览区域将更新以显示新的范围。

发送Pull Request

当你准备好提交您的Pull Request,点击Create pull request按钮:
Pull Request 提交

你会被带到一个讨论页面,在这里你可以输入一个标题和说明(可选)。你仍然可以看到,当Pull Request发送时哪些commit将包括在内。

当你你输入好标题和描述,针对commit范围做了必要的自定义,审查了要发送的commit和修改的文件,按Send pull request按钮。
Pull Request 发送按钮

Pull Request会被立即发送。你会被带往一个Pull Request讨论和审核的主页。

在你的Pull Request发送之后,任何push到你的分支的commit会被自动更新上去。如果您需要更多的改变,这尤其有用。

管理Pull Request

所有经由你发送或者审核的Pull Request都可以通过仪表盘的pull request 查看。给自定版本库的Pull Request,对于所有能够访问对应Pull Request页面的人来说,也是可见的。
已有的Pull Request 列表

Pull Request仪表板和版本库的Pull Request列表支持多种筛选和排序控件。用它们来把列表缩小到你感兴趣的Pull Request

审查建议的更改

当您收到一个Pull Request,要做的第一件事就是审查这些建议的更改。Pull Request被紧密地与底层的git仓库集成,所以你可以看到如果Request被接受,哪些commit会被合并:
commit 审核页

您还可以了解所有提交,查看所有文件更改的累计差异。
差异审核页

讨论Pull Request

审查了基本说明,commit,和累积差异后,负责应用更改的人可能有问题或意见。也许是编码风格不匹配项目的指引,或变更缺少单元测试,或者也许一切看起来不错,所有事情都准备就绪。设计这种讨论会面,旨在鼓励和关注这种类型的讨论。
Pull Request 讨论

这种讨论会面从Pull Request的原始标题和描述开始,然后从那里按时间顺序显示额外的活动。任何以下类型的活动,当发生的时候将会被关注:

  • 在Pull Request中的评论。
  • 在Pull Request分支中新提交的commit。
  • 在Pull Request范围内的commit中的存在的文件和行注释。

Pull Request的评论是Markdown语法兼容的,所以你可以嵌入图像,使用预格式化文本块,或者其他Markdown支持的格式。

查看长时间存留的Pull Request

当一个功能或bug修正去了几个月,但从来没有通过或者丢弃,你经常想要仔细看看,是什么阻止这个Pull Request被解决。查看旧的但仍然活跃的Pull Request,可以使得这个工作简化。

您可以从您的版本库的Pull Request页面查看和排序长时间存在的Pull Request。
排序Pull Request

长期存在的Pull Request是至少已经存在了一个多月,并已在过去一个月内有可见活动的。该过滤器将按这样一个排序方式显示那些长期运行的Pull Request:从创作到最新的活动的时间。(完)

matainable javascript : For-In 循环

本系列的文章都是在阅读《编写可维护的JavaScript》——Nicbolas C. Zakas 的基础上做的一些个人总结

for-in 循环

### 遍历对象

对对象使用for in循环的时候,一般情况下,都应该使用hasOwnProperty()方法来进行过滤:



var prop,
    obj = {
        a: "aaa",
        b: "bbb"
    };

for (prop in obj) {
    if (obj.hasOwnProperty(prop) {
        console.log("Property name is " + prop);
        console.log("Property value is " + obj[prop]);
    }
}


如果的确需要查询原型链,这个时候应当补充注释

var prop,
    obj = {
        a: "aaa",
        b: "bbb"
    };

for (prop in obj) { // 包含对原型链的遍历
    console.log("Property name is " + prop);
    console.log("Property value is " + obj[prop]);
}

### 不要使用for in 来遍历数组


// 不好的用法
var values = [ 1, 2, 3, 4, 5, 6, 7],
    i;
    
for (i in values) {
    console.log(values[i]);
}


不使用for in来遍历数组,是因为这样会造成一些潜在的错误,同时会有性能上面的影响。

潜在的错误:


var arr = [ 'a', 'b', 'c'],
    i;

arr.test = 'ddd';

for ( i in arr ){
    console.log(i,arr[i]);
}

/** 输出内容
 * 0 a 
 * 1 b 
 * 2 c 
 * test tset 
 * /


可见for in循环会把用户附加在数组上的一些自定义属性输出,这很可能会导致一些潜在的错误,因为这段代码的作者的目的是需要的数组成员的数据

性能问题(摘自JavaScript秘密花园):

由于 for in 循环会枚举原型链上的所有属性,唯一过滤这些属性的方式是使用 hasOwnProperty 函数, 因此会比普通的 for 循环慢上好多倍。

做个测试:


var arr = [],
    i,
    a,
    max = 100000,
    timeStart,
    timeEnd;

// 生成一个长度100000的数组
for (i = 0; i < max; i++) {
    arr[i] = i;
}

/**
 * for 循环
 */
timeStart = new Date().valueOf();
for (i = 0; i < max; i++) {
    // 无意义的一些操作
    a = arr[i];
}
timeEnd = new Date().valueOf();

console.log(timeEnd - timeStart);

/**
 * for in 循环
 */
timeStart = new Date().valueOf();
for (i in arr) {
    // 无意义的一些操作
    a = arr[i];
}
timeEnd = new Date().valueOf();

console.log(timeEnd - timeStart);



在数组长度比较小的时候,两者差距不大
甚至有的时候for in还会快一点
但是随着数组长度越来越大,两者的差距也就越来越明显

下面是一串本机的测试数据(Mac Chrome 37.0.2062.122)

数组长度 for for-in
10 0 0
1000 0 1
10000 1 6
100000 2 46
1000000 24 331
10000000 207 4362

虽然在实际项目中,数组的长度不会那么长,但是能提高一点效率总是好的