
软件开发入门教程网之MySQL NULL 值处理
MySQL NULL 值处理
我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
IS NULL: 当列的值是 NULL,此运算符返回 true。
IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
<=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。
MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。
注意:
select * , columnName1+ifnull(columnName2,0) from tableName;
columnName1,columnName2 为 int 型,当 columnName2 中,有值为 null 时,columnName1+columnName2=null, ifnull(columnName2,0) 把 columnName2 中 null 值转为 0。
在命令提示符中使用 NULL 值
以下实例中假设数据库 RUNOOB 中的表 kxdang_test_tbl 含有两列 kxdang_author 和 kxdang_count, kxdang_count 中设置插入NULL值。
实例
尝试以下实例:
创建数据表 kxdang_test_tbl
root@host# mysql -u root -p password;
Enter password:***
mysql> use RUNOOB;
Database changed
mysql> create table kxdang_test_tbl
-> (
-> kxdang_author varchar(40) NOT NULL,
-> kxdang_count INT
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('RUNOOB', 20);
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('菜鸟教程', NULL);
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('Google', NULL);
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('FK', 20);
mysql> SELECT * from kxdang_test_tbl;
+---------------+--------------+
| kxdang_author | kxdang_count |
+---------------+--------------+
| RUNOOB | 20 |
| 菜鸟教程 | NULL |
| Google | NULL |
| FK | 20 |
+---------------+--------------+
4 rows in set (0.01 sec)
以下实例中你可以看到 = 和 != 运算符是不起作用的:
mysql> SELECT FROM kxdang_test_tbl WHERE kxdang_count = NULL;
Empty set (0.00 sec)
mysql> SELECT FROM kxdang_test_tbl WHERE kxdang_count != NULL;
Empty set (0.01 sec)
查找数据表中 kxdang_test_tbl 列是否为 NULL,必须使用 IS NULL 和 IS NOT NULL,如下实例:
mysql> SELECT * FROM kxdang_test_tbl WHERE kxdang_count IS NULL;
+---------------+--------------+
| kxdang_author | kxdang_count |
+---------------+--------------+
| 菜鸟教程 | NULL |
| Google | NULL |
+---------------+--------------+
2 rows in set (0.01 sec)
mysql> SELECT * from kxdang_test_tbl WHERE kxdang_count IS NOT NULL;
+---------------+--------------+
| kxdang_author | kxdang_count |
+---------------+--------------+
| RUNOOB | 20 |
| FK | 20 |
+---------------+--------------+
2 rows in set (0.01 sec)
使用 PHP 脚本处理 NULL 值
PHP 脚本中你可以在 if...else 语句来处理变量是否为空,并生成相应的条件语句。
以下实例中 PHP 设置了 $kxdang_count 变量,然后使用该变量与数据表中的 kxdang_count 字段进行比较:
MySQL ORDER BY 测试:
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '123456'; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
if( isset($kxdang_count ))
{
$sql = "SELECT kxdang_author, kxdang_count
FROM kxdang_test_tbl
WHERE kxdang_count = $kxdang_count";
}
else
{
$sql = "SELECT kxdang_author, kxdang_count
FROM kxdang_test_tbl
WHERE kxdang_count IS NULL";
}
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo '<h2>菜鸟教程 IS NULL 测试<h2>';
echo '<table border="1"><tr><td>作者</td><td>登陆次数</td></tr>';
while($row = mysqli_fetch_array($retval, MYSQL_ASSOC))
{
echo "<tr>".
"<td>{$row['kxdang_author']} </td> ".
"<td>{$row['kxdang_count']} </td> ".
"</tr>";
}
echo '</table>';
mysqli_close($conn);
?>
输出结果如下图所示:
MySQL NULL 值处理
我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
IS NULL: 当列的值是 NULL,此运算符返回 true。
IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。
<=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。
MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。
注意:
select * , columnName1+ifnull(columnName2,0) from tableName;
columnName1,columnName2 为 int 型,当 columnName2 中,有值为 null 时,columnName1+columnName2=null, ifnull(columnName2,0) 把 columnName2 中 null 值转为 0。
在命令提示符中使用 NULL 值
以下实例中假设数据库 RUNOOB 中的表 kxdang_test_tbl 含有两列 kxdang_author 和 kxdang_count, kxdang_count 中设置插入NULL值。
实例
尝试以下实例:
创建数据表 kxdang_test_tbl
root@host# mysql -u root -p password;
Enter password:***
mysql> use RUNOOB;
Database changed
mysql> create table kxdang_test_tbl
-> (
-> kxdang_author varchar(40) NOT NULL,
-> kxdang_count INT
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('RUNOOB', 20);
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('菜鸟教程', NULL);
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('Google', NULL);
mysql> INSERT INTO kxdang_test_tbl (kxdang_author, kxdang_count) values ('FK', 20);
mysql> SELECT * from kxdang_test_tbl;
+---------------+--------------+
| kxdang_author | kxdang_count |
+---------------+--------------+
| RUNOOB | 20 |
| 菜鸟教程 | NULL |
| Google | NULL |
| FK | 20 |
+---------------+--------------+
4 rows in set (0.01 sec)
以下实例中你可以看到 = 和 != 运算符是不起作用的:
mysql> SELECT FROM kxdang_test_tbl WHERE kxdang_count = NULL;
Empty set (0.00 sec)
mysql> SELECT FROM kxdang_test_tbl WHERE kxdang_count != NULL;
Empty set (0.01 sec)
查找数据表中 kxdang_test_tbl 列是否为 NULL,必须使用 IS NULL 和 IS NOT NULL,如下实例:
mysql> SELECT * FROM kxdang_test_tbl WHERE kxdang_count IS NULL;
+---------------+--------------+
| kxdang_author | kxdang_count |
+---------------+--------------+
| 菜鸟教程 | NULL |
| Google | NULL |
+---------------+--------------+
2 rows in set (0.01 sec)
mysql> SELECT * from kxdang_test_tbl WHERE kxdang_count IS NOT NULL;
+---------------+--------------+
| kxdang_author | kxdang_count |
+---------------+--------------+
| RUNOOB | 20 |
| FK | 20 |
+---------------+--------------+
2 rows in set (0.01 sec)
使用 PHP 脚本处理 NULL 值
PHP 脚本中你可以在 if...else 语句来处理变量是否为空,并生成相应的条件语句。
以下实例中 PHP 设置了 $kxdang_count 变量,然后使用该变量与数据表中的 kxdang_count 字段进行比较:
MySQL ORDER BY 测试:
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = '123456'; // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('连接失败: ' . mysqli_error($conn));
}
// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
if( isset($kxdang_count ))
{
$sql = "SELECT kxdang_author, kxdang_count
FROM kxdang_test_tbl
WHERE kxdang_count = $kxdang_count";
}
else
{
$sql = "SELECT kxdang_author, kxdang_count
FROM kxdang_test_tbl
WHERE kxdang_count IS NULL";
}
mysqli_select_db( $conn, 'RUNOOB' );
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
echo '<h2>菜鸟教程 IS NULL 测试<h2>';
echo '<table border="1"><tr><td>作者</td><td>登陆次数</td></tr>';
while($row = mysqli_fetch_array($retval, MYSQL_ASSOC))
{
echo "<tr>".
"<td>{$row['kxdang_author']} </td> ".
"<td>{$row['kxdang_count']} </td> ".
"</tr>";
}
echo '</table>';
mysqli_close($conn);
?>
输出结果如下图所示:

2022最新上传ipa到appstore的步骤说明
最近有人提出问题,说IOS7怎么在APP store中下载软件,好多软件都提示需要ios8及以上才可以下载,而App Store里下载又不会提供给你旧版本,难倒ios7就必须升级才能下载吗?对此本人在网上查了好多资料也做了好多测试,大多数说的都是升级系统(这纯属废话,要是升级系统还用问你啊),终于皇天不负有心人,经过多次测试,我找到了一个解决办法,其实真的是非常简单,废话也不多说了,方法就是,把你的AppleId的用户名及密码让你的亲朋好友用他的苹果手机或者iPad登录(当然他的设备必须是高版本的)后先下载到他的设备上,这样你的AppleId就会记录下你的购买记录,接下来你就可以拿自己的低版本设备,用下载过该应用的AppleId登录,然后进入App Store 点击 最后一个栏目“更新”,在那里会显示当前AppleId下载过的应用,然后你点击你要下载的那个就可以了,当然也回提示当前应用版本需要IOS8及以上之类的,但是下面还有说 是否获取旧版本,这样就可以下载你当前设备可以下载的版本了。
证书我们这边可以借助辅助工具appuploader
Appuploader可以辅助在Windows、linux或mac系统直接申请iOS证书p12,及上传ipa到App Store,最方便在Windows开发上架没有苹果Mac电脑的开发者!配合本教程使用,可以快速掌握如何真机测试及上架!
点击苹果证书按钮
点击新增
输入证书密码,名称
这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码,此密码设置后没有其他地方可以找到,忘记了只能删除证书重新制作,所以请务必记住密码。还有为了安全起见,密码不要太简单。 证书名称是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是是字母和数字之类
选择证书类型
带distribution的是发布类型,带development的是开发类型。
apple类型=ios+mac,所以开发时选择ios app development和apple development 类型都是可以的
选择bundle id
只有部分类型的证书需要选择bundle id,例如推送证书。因为大部分证书是不和app关联的。而是通过描述文件profile文件关联app。
最近有人提出问题,说IOS7怎么在APP store中下载软件,好多软件都提示需要ios8及以上才可以下载,而App Store里下载又不会提供给你旧版本,难倒ios7就必须升级才能下载吗?对此本人在网上查了好多资料也做了好多测试,大多数说的都是升级系统(这纯属废话,要是升级系统还用问你啊),终于皇天不负有心人,经过多次测试,我找到了一个解决办法,其实真的是非常简单,废话也不多说了,方法就是,把你的AppleId的用户名及密码让你的亲朋好友用他的苹果手机或者iPad登录(当然他的设备必须是高版本的)后先下载到他的设备上,这样你的AppleId就会记录下你的购买记录,接下来你就可以拿自己的低版本设备,用下载过该应用的AppleId登录,然后进入App Store 点击 最后一个栏目“更新”,在那里会显示当前AppleId下载过的应用,然后你点击你要下载的那个就可以了,当然也回提示当前应用版本需要IOS8及以上之类的,但是下面还有说 是否获取旧版本,这样就可以下载你当前设备可以下载的版本了。
证书我们这边可以借助辅助工具appuploader
Appuploader可以辅助在Windows、linux或mac系统直接申请iOS证书p12,及上传ipa到App Store,最方便在Windows开发上架没有苹果Mac电脑的开发者!配合本教程使用,可以快速掌握如何真机测试及上架!
点击苹果证书按钮
点击新增
输入证书密码,名称
这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码,此密码设置后没有其他地方可以找到,忘记了只能删除证书重新制作,所以请务必记住密码。还有为了安全起见,密码不要太简单。 证书名称是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是是字母和数字之类
选择证书类型
带distribution的是发布类型,带development的是开发类型。
apple类型=ios+mac,所以开发时选择ios app development和apple development 类型都是可以的
选择bundle id
只有部分类型的证书需要选择bundle id,例如推送证书。因为大部分证书是不和app关联的。而是通过描述文件profile文件关联app。

如何用苹果app完成ipa安装
当打包完ipa文件后,ipa文件无法直接安装,只能添加udid安装到手机,或者上架才能安装,这里,我分享下使用本站工具上传ipa到app store,无需mac电脑完成ipa文件上架的详细步骤:
1、首先,上架必须要有苹果开发者账号和已经生成了app store类型的打包证书.
2、访问苹果开发者中心,登录进入苹果开发者开发中心: Apple Developer
3、进入控制台后,点击app store connect,进入到app store的管理页面,你是第一次上传,则还没创建app,你需要先创建app。假如不是第一次上传,则无需重新创建app,如下图:
4、已经创建app后,点击app名称就进入填写好各项资料,创建新版本。
5、填写新版本的资料过程中它会要求你选择一个构建版本,但是它提示,这个构建版本要使用旁边的xcode或transport等工具提交,不能在网页上提交。而旁边的工具都需要mac电脑才能安装。这里不用担心,这里我们可以不使用官方提供的工具,因为我们本站提供了上传ipa的工具,工具的地址:www.appuploader.net/
6、登录本站(appuploader)控制台,即可上传ipa,如图:
7、选择文件进行上传,过程中还需要输入苹果开发者中心的专用密码和开发者账号。注意要填写专用密码,不是登录密码。
8、大概过几分钟,就可以上传成功,但要注意,上传成功后苹果开发者中心不能马上见到,因为苹果开发者中心还要验证app的程序是否有其他版本兼容和api过期问题,大概过30分钟左右,就可以在苹果开发者中心的构建版本见到了,选择刚上传的构建版本,你就可以继续在苹果开发者中心继续上架app到app store了。
9、上架的过程中还会要求我们提供各种设备的屏幕快照(截屏),这个比较难搞,因为我们可能没有这么多类型的ios设备怎么截屏。你可以使用本站提供的合成工具自动生成ios截屏。
证书我们这边可以借助辅助工具appuploader
Appuploader可以辅助在Windows、linux或mac系统直接申请iOS证书p12,及上传ipa到App Store,最方便在Windows开发上架没有苹果Mac电脑的开发者!配合本教程使用,可以快速掌握如何真机测试及上架!
点击苹果证书按钮
点击新增
输入证书密码,名称
这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码,此密码设置后没有其他地方可以找到,忘记了只能删除证书重新制作,所以请务必记住密码。还有为了安全起见,密码不要太简单。 证书名称是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是是字母和数字之类
选择证书类型
带distribution的是发布类型,带development的是开发类型。
apple类型=ios+mac,所以开发时选择ios app development和apple development 类型都是可以的
选择bundle id
只有部分类型的证书需要选择bundle id,例如推送证书。因为大部分证书是不和app关联的。而是通过描述文件profile文件关联app。
当打包完ipa文件后,ipa文件无法直接安装,只能添加udid安装到手机,或者上架才能安装,这里,我分享下使用本站工具上传ipa到app store,无需mac电脑完成ipa文件上架的详细步骤:
1、首先,上架必须要有苹果开发者账号和已经生成了app store类型的打包证书.
2、访问苹果开发者中心,登录进入苹果开发者开发中心: Apple Developer
3、进入控制台后,点击app store connect,进入到app store的管理页面,你是第一次上传,则还没创建app,你需要先创建app。假如不是第一次上传,则无需重新创建app,如下图:
4、已经创建app后,点击app名称就进入填写好各项资料,创建新版本。
5、填写新版本的资料过程中它会要求你选择一个构建版本,但是它提示,这个构建版本要使用旁边的xcode或transport等工具提交,不能在网页上提交。而旁边的工具都需要mac电脑才能安装。这里不用担心,这里我们可以不使用官方提供的工具,因为我们本站提供了上传ipa的工具,工具的地址:www.appuploader.net/
6、登录本站(appuploader)控制台,即可上传ipa,如图:
7、选择文件进行上传,过程中还需要输入苹果开发者中心的专用密码和开发者账号。注意要填写专用密码,不是登录密码。
8、大概过几分钟,就可以上传成功,但要注意,上传成功后苹果开发者中心不能马上见到,因为苹果开发者中心还要验证app的程序是否有其他版本兼容和api过期问题,大概过30分钟左右,就可以在苹果开发者中心的构建版本见到了,选择刚上传的构建版本,你就可以继续在苹果开发者中心继续上架app到app store了。
9、上架的过程中还会要求我们提供各种设备的屏幕快照(截屏),这个比较难搞,因为我们可能没有这么多类型的ios设备怎么截屏。你可以使用本站提供的合成工具自动生成ios截屏。
证书我们这边可以借助辅助工具appuploader
Appuploader可以辅助在Windows、linux或mac系统直接申请iOS证书p12,及上传ipa到App Store,最方便在Windows开发上架没有苹果Mac电脑的开发者!配合本教程使用,可以快速掌握如何真机测试及上架!
点击苹果证书按钮
点击新增
输入证书密码,名称
这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码,此密码设置后没有其他地方可以找到,忘记了只能删除证书重新制作,所以请务必记住密码。还有为了安全起见,密码不要太简单。 证书名称是你为了在证书列表里面便于区别的一个字符,自己好辨识就可以,尽量是是字母和数字之类
选择证书类型
带distribution的是发布类型,带development的是开发类型。
apple类型=ios+mac,所以开发时选择ios app development和apple development 类型都是可以的
选择bundle id
只有部分类型的证书需要选择bundle id,例如推送证书。因为大部分证书是不和app关联的。而是通过描述文件profile文件关联app。

苹果应用上架后多久可以下载
OS上架
iOS APP上架App Store其中一个步骤就是要把ipa文件上传到App Store!
下面进行步骤介绍!
利用Appuploader这个软件,可以在Windows、Linux或Mac系统中申请ios和上传IPA到App Store Connect。
非常的方便,没有Mac也可以用Appuploader在Windows电脑上传ipa到App Store Connect后台。
Appuploader
1、因为苹果开发者账号现在都开通了双重认证,所以需要生成一个上传专用密码才能上传ipa文件。
打开网站
登录苹果开发者账号
登录进去找到安全项目,点击生成专用密码。
密码标签随便输入,123,app等之类的都行。
点击创建生成,(注意密码标签不是专用密码,是由苹果系统生成的一串密码)专用密码就是下面这个样子的密码,把这个密码复制,打开Appuploader
登录Appuploader软件,点击右上角,选择设置,把上传专用密码复制上去,同时勾选上保存密码 ,点击Save保存,然后再回去提交ipa上传就可以正常上传了。
6.1输入专用密码点击OK保存后,点击提交
6.2选择刚生成的ipa包
6.3Appuploader将自动上传你的IPA,包如果很大需要上传一段时间,当出现以下提示时(packages were uploaded successfully 进度条蓝色),说明上传成功。
6.4(这一步一定要认真看下文字说明,很多人这里理不清)
packages were uploaded successfully 进度条蓝色,ipa上传成功后 ,登录iTunes Connect 后台查看上传的ipa
进入APP,点击活动,所有构建版本选项(下图所示) ,这里会显示上传成功的构建版本,如果ipa包没问题刚上传会显示正在处理!
如果你发现没有出现构建版本 ,或者刷新一下构建版本消失了,出现这个问题说明你上传的这个ipa包有问题,苹果会发送具体原因到邮箱(开发者账号就是邮箱地址),登录邮箱查看反馈邮件,修改错误重新打包上传。
修改错误重新打包的时候记得加下版本号,比如你刚上传的是1.0版本,重新打包时增加下版本号如1.1,如果还是跟之前上传过相同的版本号的ipa文件,上传不了。
IOS开发工具官网地址 http://www.applicationloader.net/
最新版本已经优化了没支付688给apple的账号登录流程,无需再安装其他软件。 立即下载最新版本 在appuploader官网首页下载,如果您是windows电脑,则选择点击 windows版,如果是mac 电脑则选择 mac版 下载后解压到电脑中就安装完成了。
windows启动
windows系统里面,解压后双击appuploader.exe就可以直接运行了。 尽量不要放c盘,不要放带中文路径的盘。如果不行可以右击然后选择管理员运行试试。
mac和linux 电脑启动处理
如果是在mac或者linux电脑中,需要使用命令行,对appuploader修改权限。 在appuploader解压后的目录,打开命令行工具,执行下面的命令,使appuploader具备可执行权限。就可以双击启动了。
sudo chmod -R 777 ./*
不会命令行的也可以试试,把各项权限都改查可执行。 mac电脑修改文件权限
部分功能不可用处理
有些电脑可能会对runtime下的组件进行权限控制,导致无法调用组件,例如无法上传,可以双击运行下试试是否被系统权限阻止,正常会是一个黑色框一闪而过,如果系统提示权限错误,则放开权限,允许执行。
驱动安装
安装测试,自动读取设备udid需要安装苹果手机驱动,驱动下载地址。部分电脑缺少程序运行的基本库,可以安装驱动解决。下载后把文件夹内的exe都安装后重启工具。 下载apple手机驱动
如果是未支付688的apple账号,还需要安装icloud icloud下载地址:https://support.apple.com/zh-cn/HT204283 下载icloud
OS上架
iOS APP上架App Store其中一个步骤就是要把ipa文件上传到App Store!
下面进行步骤介绍!
利用Appuploader这个软件,可以在Windows、Linux或Mac系统中申请ios和上传IPA到App Store Connect。
非常的方便,没有Mac也可以用Appuploader在Windows电脑上传ipa到App Store Connect后台。
Appuploader
1、因为苹果开发者账号现在都开通了双重认证,所以需要生成一个上传专用密码才能上传ipa文件。
打开网站
登录苹果开发者账号
登录进去找到安全项目,点击生成专用密码。
密码标签随便输入,123,app等之类的都行。
点击创建生成,(注意密码标签不是专用密码,是由苹果系统生成的一串密码)专用密码就是下面这个样子的密码,把这个密码复制,打开Appuploader
登录Appuploader软件,点击右上角,选择设置,把上传专用密码复制上去,同时勾选上保存密码 ,点击Save保存,然后再回去提交ipa上传就可以正常上传了。
6.1输入专用密码点击OK保存后,点击提交
6.2选择刚生成的ipa包
6.3Appuploader将自动上传你的IPA,包如果很大需要上传一段时间,当出现以下提示时(packages were uploaded successfully 进度条蓝色),说明上传成功。
6.4(这一步一定要认真看下文字说明,很多人这里理不清)
packages were uploaded successfully 进度条蓝色,ipa上传成功后 ,登录iTunes Connect 后台查看上传的ipa
进入APP,点击活动,所有构建版本选项(下图所示) ,这里会显示上传成功的构建版本,如果ipa包没问题刚上传会显示正在处理!
如果你发现没有出现构建版本 ,或者刷新一下构建版本消失了,出现这个问题说明你上传的这个ipa包有问题,苹果会发送具体原因到邮箱(开发者账号就是邮箱地址),登录邮箱查看反馈邮件,修改错误重新打包上传。
修改错误重新打包的时候记得加下版本号,比如你刚上传的是1.0版本,重新打包时增加下版本号如1.1,如果还是跟之前上传过相同的版本号的ipa文件,上传不了。
IOS开发工具官网地址 http://www.applicationloader.net/
最新版本已经优化了没支付688给apple的账号登录流程,无需再安装其他软件。 立即下载最新版本 在appuploader官网首页下载,如果您是windows电脑,则选择点击 windows版,如果是mac 电脑则选择 mac版 下载后解压到电脑中就安装完成了。
windows启动
windows系统里面,解压后双击appuploader.exe就可以直接运行了。 尽量不要放c盘,不要放带中文路径的盘。如果不行可以右击然后选择管理员运行试试。
mac和linux 电脑启动处理
如果是在mac或者linux电脑中,需要使用命令行,对appuploader修改权限。 在appuploader解压后的目录,打开命令行工具,执行下面的命令,使appuploader具备可执行权限。就可以双击启动了。
sudo chmod -R 777 ./*
不会命令行的也可以试试,把各项权限都改查可执行。 mac电脑修改文件权限
部分功能不可用处理
有些电脑可能会对runtime下的组件进行权限控制,导致无法调用组件,例如无法上传,可以双击运行下试试是否被系统权限阻止,正常会是一个黑色框一闪而过,如果系统提示权限错误,则放开权限,允许执行。
驱动安装
安装测试,自动读取设备udid需要安装苹果手机驱动,驱动下载地址。部分电脑缺少程序运行的基本库,可以安装驱动解决。下载后把文件夹内的exe都安装后重启工具。 下载apple手机驱动
如果是未支付688的apple账号,还需要安装icloud icloud下载地址:https://support.apple.com/zh-cn/HT204283 下载icloud

软件开发入门教程网之C++ 信号处理
信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。
有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中。
信号
描述
SIGABRT
程序的异常终止,如调用 abort。
SIGFPE
错误的算术运算,比如除以零或导致溢出的操作。
SIGILL
检测非法指令。
SIGINT
程序终止(interrupt)信号。
SIGSEGV
非法访问内存。
SIGTERM
发送到程序的终止请求。
signal() 函数
C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:
void (signal (int sig, void (func)(int)))(int);这个看起来有点费劲,以下语法格式更容易理解:
signal(registered signal, signal handler)这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。
让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果:
Going to sleep....
Going to sleep....
Going to sleep....现在,按 Ctrl+C 来中断程序,您会看到程序捕获信号,程序打印如下内容并退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.raise() 函数
您可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:
int raise (signal sig);在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
int i = 0;
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果,并会自动退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。
有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中。
信号
描述
SIGABRT
程序的异常终止,如调用 abort。
SIGFPE
错误的算术运算,比如除以零或导致溢出的操作。
SIGILL
检测非法指令。
SIGINT
程序终止(interrupt)信号。
SIGSEGV
非法访问内存。
SIGTERM
发送到程序的终止请求。
signal() 函数
C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:
void (signal (int sig, void (func)(int)))(int);这个看起来有点费劲,以下语法格式更容易理解:
signal(registered signal, signal handler)这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。
让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果:
Going to sleep....
Going to sleep....
Going to sleep....现在,按 Ctrl+C 来中断程序,您会看到程序捕获信号,程序打印如下内容并退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.raise() 函数
您可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:
int raise (signal sig);在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
int i = 0;
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果,并会自动退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

软件开发入门教程网之C++ 标准库
C++ 标准库可以分为两部分:
• 标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自 C 语言。
• 面向对象类库: 这个库是类及其相关函数的集合。
C++ 标准库包含了所有的 C 标准库,为了支持类型安全,做了一定的添加和修改。
标准函数库
标准函数库分为以下几类:
• 输入/输出 I/O
• 字符串和字符处理
• 数学
• 时间、日期和本地化
• 动态分配
• 其他
• 宽字符函数
面向对象类库
标准的 C++ 面向对象类库定义了大量支持一些常见操作的类,比如输入/输出 I/O、字符串处理、数值处理。面向对象类库包含以下内容:
• 标准的 C++ I/O 类
• String 类
• 数值类
• STL 容器类
• STL 算法
• STL 函数对象
• STL 迭代器
• STL 分配器
• 本地化库
• 异常处理类
• 杂项支持库
C++ 标准库可以分为两部分:
• 标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自 C 语言。
• 面向对象类库: 这个库是类及其相关函数的集合。
C++ 标准库包含了所有的 C 标准库,为了支持类型安全,做了一定的添加和修改。
标准函数库
标准函数库分为以下几类:
• 输入/输出 I/O
• 字符串和字符处理
• 数学
• 时间、日期和本地化
• 动态分配
• 其他
• 宽字符函数
面向对象类库
标准的 C++ 面向对象类库定义了大量支持一些常见操作的类,比如输入/输出 I/O、字符串处理、数值处理。面向对象类库包含以下内容:
• 标准的 C++ I/O 类
• String 类
• 数值类
• STL 容器类
• STL 算法
• STL 函数对象
• STL 迭代器
• STL 分配器
• 本地化库
• 异常处理类
• 杂项支持库

http://kxdang.com/topic/cplusplus/cpp-signal-handling.html
软件开发入门教程网之C++ 信号处理
信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。
有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中。
信号
描述
SIGABRT
程序的异常终止,如调用 abort。
SIGFPE
错误的算术运算,比如除以零或导致溢出的操作。
SIGILL
检测非法指令。
SIGINT
程序终止(interrupt)信号。
SIGSEGV
非法访问内存。
SIGTERM
发送到程序的终止请求。
signal() 函数
C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:
void (signal (int sig, void (func)(int)))(int);这个看起来有点费劲,以下语法格式更容易理解:
signal(registered signal, signal handler)这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。
让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果:
Going to sleep....
Going to sleep....
Going to sleep....现在,按 Ctrl+C 来中断程序,您会看到程序捕获信号,程序打印如下内容并退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.raise() 函数
您可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:
int raise (signal sig);在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
int i = 0;
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果,并会自动退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.
软件开发入门教程网之C++ 信号处理
信号是由操作系统传给进程的中断,会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。
有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal> 中。
信号
描述
SIGABRT
程序的异常终止,如调用 abort。
SIGFPE
错误的算术运算,比如除以零或导致溢出的操作。
SIGILL
检测非法指令。
SIGINT
程序终止(interrupt)信号。
SIGSEGV
非法访问内存。
SIGTERM
发送到程序的终止请求。
signal() 函数
C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:
void (signal (int sig, void (func)(int)))(int);这个看起来有点费劲,以下语法格式更容易理解:
signal(registered signal, signal handler)这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。
让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(1){
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果:
Going to sleep....
Going to sleep....
Going to sleep....现在,按 Ctrl+C 来中断程序,您会看到程序捕获信号,程序打印如下内容并退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.raise() 函数
您可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:
int raise (signal sig);在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例:
实例
include <iostream>
include <csignal>
include <unistd.h>
using namespace std;
void signalHandler( int signum )
{
cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭
// 终止程序
exit(signum);
}
int main ()
{
int i = 0;
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
while(++i){
cout << "Going to sleep...." << endl;
if( i == 3 ){
raise( SIGINT);
}
sleep(1);
}
return 0;
}当上面的代码被编译和执行时,它会产生下列结果,并会自动退出:
Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

软件开发入门教程网之C++ 引用
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
C++ 引用 vs 指针
引用很容易与指针混淆,它们之间有三个主要的不同:
• 不存在空引用。引用必须连接到一块合法的内存。
• 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
• 引用必须在创建时被初始化。指针可以在任何时间被初始化。
C++ 中创建引用
试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。因此,您可以通过原始变量名称或引用来访问变量的内容。例如:
int i = 17;我们可以为 i 声明引用变量,如下所示:
int& r = i;
double& s = d;在这些声明中,& 读作引用。因此,第一个声明可以读作 "r 是一个初始化为 i 的整型引用",第二个声明可以读作 "s 是一个初始化为 d 的 double 型引用"。下面的实例使用了 int 和 double 引用:
实例
include <iostream>
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}当上面的代码被编译和执行时,它会产生下列结果:
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7引用通常用于函数参数列表和函数返回值。下面列出了 C++ 程序员必须清楚的两个与 C++ 引用相关的重要概念:
概念
描述
把引用作为参数
C++ 支持把引用作为参数传给函数,这比传一般的参数更安全。
把引用作为返回值
可以从 C++ 函数中返回引用,就像返回其他数据类型一样。
引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。
C++ 引用 vs 指针
引用很容易与指针混淆,它们之间有三个主要的不同:
• 不存在空引用。引用必须连接到一块合法的内存。
• 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
• 引用必须在创建时被初始化。指针可以在任何时间被初始化。
C++ 中创建引用
试想变量名称是变量附属在内存位置中的标签,您可以把引用当成是变量附属在内存位置中的第二个标签。因此,您可以通过原始变量名称或引用来访问变量的内容。例如:
int i = 17;我们可以为 i 声明引用变量,如下所示:
int& r = i;
double& s = d;在这些声明中,& 读作引用。因此,第一个声明可以读作 "r 是一个初始化为 i 的整型引用",第二个声明可以读作 "s 是一个初始化为 d 的 double 型引用"。下面的实例使用了 int 和 double 引用:
实例
include <iostream>
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}当上面的代码被编译和执行时,它会产生下列结果:
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7引用通常用于函数参数列表和函数返回值。下面列出了 C++ 程序员必须清楚的两个与 C++ 引用相关的重要概念:
概念
描述
把引用作为参数
C++ 支持把引用作为参数传给函数,这比传一般的参数更安全。
把引用作为返回值
可以从 C++ 函数中返回引用,就像返回其他数据类型一样。

App 中使用webview 跳转第三方提供的支付宝H5,打开支付宝失败
App 中使用webview 跳转第三方提供的支付宝H5, H5中有调用下载支付宝与跳转支付宝功能,经过测试安卓可以跳转,ios无法跳转,两端都可进行下载操作。请问问题可能是出在哪块?ios端浏览器已做过测试,只有qq浏览器不能跳转,其他正常
App 中使用webview 跳转第三方提供的支付宝H5, H5中有调用下载支付宝与跳转支付宝功能,经过测试安卓可以跳转,ios无法跳转,两端都可进行下载操作。请问问题可能是出在哪块?ios端浏览器已做过测试,只有qq浏览器不能跳转,其他正常