Lockprofile什么意思啊汉语意思

MySQL的查询过程分析
MySQL的查询过程分析
MySQL查询过程
关系型数据库管理系统查询处理一般分为4个阶段:
怎么验证这几个阶段对应在MySQL的关系呢?
这里实验的数据库版本:5.6.16-64.2-56
OS:CentOS release 6.5
Kernel:2.6.32-431.el6.x86_64
创建测试库及表、数据:
root@localhost[(none)]:14: &CREATE DATABASE querydb /!40100 DEFAULT CHARACTER SET utf8 /;
Query OK, 1 row affected (0.00 sec)
root@localhost[(none)]:15: &
Database changed
root@localhost[querydb]:20: &create table t(id int auto_increment ,name varchar(50),primary key(id)) engine=
Query OK, 0 rows affected (0.02 sec)
root@localhost[querydb]:21: &insert into t values(NULL,'a');
Query OK, 1 row affected (0.00 sec)
root@localhost[querydb]:21: &insert into t values(NULL,'b');
Query OK, 1 row affected (0.00 sec)
root@localhost[querydb]:21: &insert into t values(NULL,'c');
Query OK, 1 row affected (0.01 sec)
打开MySQL的profile
root@localhost[querydb]:21: &set @@profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
首先我们来查询一条正常的sql语句,看MySQL内部进行哪些操作。
root@localhost[querydb]:22: &select id,
| id | name |
3 rows in set (0.00 sec)
root@localhost[querydb]:24: &
| Query_ID | Duration
1 | 0. | select id,name from t |
1 row in set, 1 warning (0.00 sec)
root@localhost[querydb]:24: &show profile for query 1;
| Duration |
| starting
| 0.000313 |
| checking permissions | 0.000029 |
| Opening tables
| 0.000073 |
| 0.000058 |
| System lock
| 0.000066 |
| optimizing
| 0.000007 |
| statistics
| 0.000044 |
| preparing
| 0.000025 |
| executing
| 0.000002 |
| Sending data
| 0.000321 |
| 0.000007 |
| query end
| 0.000018 |
| closing tables
| 0.000018 |
| freeing items
| 0.000017 |
| cleaning up
| 0.000038 |
ows in set, 1 warning (0.00 sec)
从上面大体上可以看出,
首先检查权限,权限检查完后open table操作,然后进行对元数据进行lock操作、然后优化、预编译、最后执行,到Sending data时,这时已经推送到存储引擎层了进行拉取数据。最后释放lock、关闭表并进行清理操作。
先说说各个阶段的特征:
starting:语法分析与词法分析阶段
checking permissions:用户权限检查
Opening tables:表权限检查
init:表的列权限检查
System lock:获得表的一些lock信息
optimizing:逻辑优化(代数优化),主要RBO优化
statistics:物理优化(非代数优化),主要是CBO优化
preparing和executing:生成代码并执行
Sending data:也有可能包括执行、提取和发送数据的过程中。
一、查询分析
1.模拟sql关键字错误
root@localhost[querydb]:31: &selectt id,
ERROR ): You have an error in your SQL check the manual that corresponds to your MySQL server version for the right syntax to use near 'selectt id,name from t' at line 1
root@localhost[querydb]:31: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t |
2 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:32: &show profile for query 2;
| Duration |
| starting
| 0.000154 |
| freeing items | 0.000026 |
| cleaning up
| 0.000043 |
3 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:45: &select id,name fr0
ERROR ): You have an error in your SQL check the manual that corresponds to your MySQL server version for the right syntax to use near 't' at line 1
root@localhost[querydb]:45: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t |
3 | 0. | select id,name fr0m t
3 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:45: &show profile for query 3;
| Duration |
| starting
| 0.000134 |
| freeing items | 0.000018 |
| cleaning up
| 0.000036 |
3 rows in set, 1 warning (0.00 sec)
通过对比发现,starting应该是进行语法分析和词法分析。
为什么要进行语法分析和词法分析?
其实跟我们平时的母语的造句一样,比如:
这个四个字
按照我们人正常的逻辑造句应该是:我去吃饭
但计算机就不一样了,可能会出现好多:
计算机会根据一定的规则,就像我们的主谓宾格式造句一样,从中组合,但有一种可能,就是组合了即没有语法错误也没有词法错误但意思不一样的情况。这里假设:我要吃饭和要我吃饭,语法和词法都没有错误,但语义不同,这时计算机就要进行语义分析了。
这里面的判断规则有自动机进行判断,也叫图灵机(是伟大的计算机科学之父:图灵 发明的,图灵奖想必大家都熟悉吧^_^),不过龙书(编译原理)里会有详细介绍
二、查询检查
root@localhost[querydb]:45: &select ida,
#表存在,字段不存在
ERROR ): Unknown column 'ida' in 'field list'
root@localhost[querydb]:19: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t |
3 | 0. | select id,name fr0m t
4 | 0. | select ida,name from t |
4 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:19: &show profile for query 4;
| Duration |
| starting
| 0.000531 |
| checking permissions | 0.000037 |
| Opening tables
| 0.000133 |
| 0.000116 |
| 0.000017 |
| query end
| 0.000018 |
| closing tables
| 0.000027 |
| freeing items
| 0.000032 |
| cleaning up
| 0.000052 |
9 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:19: &select id,
#id,name是表t的字段,而tab表不存在
ERROR ): Table 'querydb.tab' doesn't exist
root@localhost[querydb]:23: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t
3 | 0. | select id,name fr0m t
4 | 0. | select ida,name from t
5 | 0. | select id,name from tab |
5 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:23: &show profile for query 5;
| Duration |
| starting
| 0.000621 |
| checking permissions | 0.000039 |
| Opening tables
| 0.000367 |
感觉是不是哪里
| query end
| 0.000023 |
不对劲,是不是
| closing tables
| 0.000006 |
少了init阶段
| freeing items
| 0.000055 |
| cleaning up
| 0.000066 |
7 rows in set, 1 warning (0.00 sec)
所以从上面可以观察到,这里checking permissions你可以进行测试。这里我不在进行测试。【赋予用户test什么权限都没有:grant usage on . to test@'%' identified by 'test';和赋予test2用户只有查询t表中id列的权限:grant select(id) on querydb.t to test2@'%' identified by 'test2';】,这里测试略
checking permissions: 对MySQL的连接用户进行权限检查。
Opening tables: 对表权限进行检查。
init阶段:对表中的列进行权限检查。
三、检查优化
实验的sql语句:
select id,
select id,name from t where 0=1;
三个语句查看其变化。
root@localhost[querydb]:36: &select 1;
1 row in set (0.00 sec)
root@localhost[querydb]:36: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t
3 | 0. | select id,name fr0m t
4 | 0. | select ida,name from t
5 | 0. | select id,name from tab
6 | 0. | select id,name,abc
7 | 0. | select 1
7 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:36: &show profile for query 7;
| Duration |
| starting
| 0.000196 |
| checking permissions | 0.000006 |
| Opening tables
| 0.000007 |
| 0.000016 |
| optimizing
| 0.000010 |
| executing
| 0.000013 |
| 0.000008 |
| query end
| 0.000006 |
| closing tables
| 0.000001 |
| freeing items
| 0.000014 |
| cleaning up
| 0.000019 |
11 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:36: &select id,
| id | name |
3 rows in set (0.00 sec)
root@localhost[querydb]:38: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t
3 | 0. | select id,name fr0m t
4 | 0. | select ida,name from t
5 | 0. | select id,name from tab
6 | 0. | select id,name,abc
7 | 0. | select 1
8 | 0. | select id,name from t
8 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:38: &show profile for query 8;
| Duration |
| starting
| 0.000274 |
| checking permissions | 0.000024 |
| Opening tables
| 0.000059 |
| 0.000036 |
| System lock
| 0.000029 |
| optimizing
| 0.000008 |
| statistics
| 0.000031 |
| preparing
| 0.000021 |
| executing
| 0.000002 |
| Sending data
| 0.000172 |
| 0.000011 |
| query end
| 0.000012 |
| closing tables
| 0.000013 |
| freeing items
| 0.000018 |
| cleaning up
| 0.000031 |
15 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:38: &select id,name from t where 0=1;
Empty set (0.00 sec)
root@localhost[querydb]:41: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t
3 | 0. | select id,name fr0m t
4 | 0. | select ida,name from t
5 | 0. | select id,name from tab
6 | 0. | select id,name,abc
7 | 0. | select 1
8 | 0. | select id,name from t
9 | 0. | select id,name from t where 0=1 |
9 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:41: &show profile for query 9;
| Duration |
| starting
| 0.000279 |
| checking permissions | 0.000015 |
| Opening tables
| 0.000046 |
| 0.000057 |
| System lock
| 0.000019 |
| optimizing
| 0.000025 |
| executing
| 0.000014 |
| 0.000005 |
| query end
| 0.000008 |
| closing tables
| 0.000010 |
| freeing items
| 0.000020 |
| cleaning up
| 0.000089 |
12 rows in set, 1 warning (0.00 sec)
为了便于观察,我这里查看其语句的执行计划然后看执行的语句。
下面输出的有点不好看,可以看下面的截图。
root@localhost[querydb]:10: &explain extended select id,name from t
where 0=1;
| id | select_type | table | type | possible_keys | key
| key_len | ref
| rows | filtered | Extra
1 | SIMPLE
| NULL | NULL
| NULL | NULL
| NULL | NULL |
NULL | Impossible WHERE |
1 row in set, 1 warning (0.00 sec)
root@localhost[querydb]:11: &
| Level | Code | Message
| 1003 | / select#1 / select querydb.t.id AS id,querydb.t.name AS name from querydb.t where 0 |
1 row in set (0.00 sec)
通过三个sql语句的执行情况发现。
optimizing阶段:为代数优化阶段
statistics和preparing阶段:为物理优化阶段,从字面信息上来看,可以理解是收集统计信息,生成执行计划,选择最优的存取路径进行执行。
同时有没有发现Sending data,说明这时已经到存储引擎层了去拉取数据,对比上面select 1和where 0=1 都没有Sending data,更可以很好理解,但这里有个问题?MySQL层和存储引擎层是通过接口实现的,当查询的结果返回时怎么知道返回哪个线程呢?其实在内部,每个查询都会分配一个查询线程ID的,根据线程ID编号来的。
root@localhost[querydb]:41: &select id,
| id | name |
3 rows in set (0.00 sec)
root@localhost[querydb]:15: &
| Query_ID | Duration
1 | 0. | select id,name from t
2 | 0. | selectt id,name from t
3 | 0. | select id,name fr0m t
4 | 0. | select ida,name from t
5 | 0. | select id,name from tab
6 | 0. | select id,name,abc
7 | 0. | select 1
8 | 0. | select id,name from t
9 | 0. | select id,name from t where 0=1 |
10 | 0. | select id,name from t
10 rows in set, 1 warning (0.00 sec)
root@localhost[querydb]:15: &show profile for query 10;
| Duration |
| starting
| 0.000763 |
| checking permissions | 0.000050 |
| Opening tables
| 0.000184 |
| 0.000178 |
| System lock
| 0.000076 |
| optimizing
| 0.000025 |
| statistics
| 0.000095 |
| preparing
| 0.000055 |
| executing
| 0.000002 |
| Sending data
| 0.000335 |
| 0.000018 |
| query end
| 0.000028 |
| closing tables
| 0.000023 |
| freeing items
| 0.000041 |
| cleaning up
| 0.000076 |
15 rows in set, 1 warning (0.00 sec)
executing:为执行阶段了。
这里还有一个System lock阶段:其实当执行DDL、DML操作时,MySQL会在内部对表的元数据进行加锁还有其他的锁,比如S锁,X锁,IX锁,IS锁等,用于解决或者保证DDL操作与DML操作之间的一致性。【可以参看&&或事务处理与实现】
参考书籍:
【编译原理】 [美] Alfred V.Aho,[美] Monica S.Lam,[美] Ravi Sethi 等 著;赵建华,郑滔 等 译
【数据库系统概论 】
王珊,萨师煊 著
【数据库查询优化器的艺术:原理解析与SQL性能优化】
【InnoDB存储引擎技术内幕】 姜承尧 著
【事务处理与实现】
用云栖社区APP,舒服~
【云栖快讯】Apache旗下顶级开源盛会 HBasecon Asia 2018将于8月17日在京举行,现场仅600席,免费赠票领取入口&&
MySQL 是全球最受欢迎的开源数据库,阿里云MySQL版 通过深度的内核优化和独享实例提供...
阿里云推出的一款移动App数据统计分析产品,为开发者提供一站式数据化运营服务
阿里巴巴自主研发的海量数据实时高并发在线分析云计算服务,使得您可以在毫秒级针对千亿级数据进行...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效...
阿里云总监课正式启航chenjiazhu
orzdba查看读写./&--mysql -S /data/mysql30001/mysql.sock 语句查看读写命令数量,以及数据库TPS,传输的大小
查看processlist及其statemysql -uroot -p -S /data/mysql30001/mysql.sock, 密码sitMysql或者
&mysql&-usa_test&-pymtcs@2016&-S&&/data/mysql30001/mysql.sock&&select * from information_schema.&
&&该语句不显示全部语句&
查看当前进程的SQL语句,注意其STATE (以下一段引用百度)
在processlist中,看到哪些运行状态时要引起关注,主要有下面几个:状态
copy to tmp table
执行ALTER TABLE修改表结构时 建议: 放在凌晨执行或者采用类似pt-osc工具
Copying to tmp table
拷贝数据到内存中的,常见于GROUP BY操作时 建议: 创建适当的索引
Copying to tmp table on disk
临时结果集太大,内存中放不下,需要将内存中的拷贝到磁盘上,形成 #sql***.MYD、#sql***.MYI(在5.6及更高的版本,可以改成InnoDB引擎了,可以参考选项 default_tmp_storage_engine ) 建议: 创建适当的索引,并且适当加大 sort_buffer_size/tmp_table_size/max_heap_table_size
Creating sort index
当前的SELECT中需要用到临时表在进行ORDER BY排序 建议: 创建适当的索引
Creating tmp table
创建基于内存或磁盘的临时表,当从内存转成磁盘的临时表时,状态会变成:Copying to tmp table on disk 建议: 创建适当的索引,或者少用UNION、视图(VIEW)之类的
Reading from net
表示server端正通过网络读取客户端发送过来的请求 建议: 减小客户端发送数据包大小,提高/质量
Sending data
从server端发送数据到客户端,也有可能是接收层返回的数据,再发送给客户端,数据量很大时尤其经常能看见备注:Sending Data不是网络发送,是从硬盘读取,发送到网络是Writing to net 建议: 通过索引或加上LIMIT,减少需要扫描并且发送给客户端的数据量
Sorting result
正在对结果进行排序,类似Creating sort index,不过是正常表,而不是在内存表中进行排序 建议: 创建适当的索引
statistics
进行以便解析执行计划,如果状态比较经常出现,有可能是磁盘IO性能很差建议: 查看当前io性能状态,例如iowait
Waiting for global read lock
FLUSH TABLES WITH READ LOCK整等待全局读锁 建议: 不要对线上业务数据库加上全局读锁,通常是备份引起,可以放在业务低谷期间执行或者放在slave服务器上执行备份
Waiting for tables,Waiting for table flush
FLUSH TABLES, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, OPTIMIZE TABLE等需要刷新表结构并重新打开 建议: 不要对线上业务数据库执行这些操作,可以放在业务低谷期间执行
Waiting for lock_type lock
等待各种类型的锁:o Waiting for event metadata locko Waiting for global read locko Waiting for schema metadata locko Waiting for stored function metadata locko Waiting for stored procedure metadata locko Waiting for table level locko Waiting for table metadata locko Waiting for trigger metadata lock建议:比较常见的是上面提到的global read lock以及table metadata lock,建议不要对线上业务数据库执行这些操作,可以放在业务低谷期间执行。如果是table level lock,通常是因为还在使用MyISAM引擎表,赶紧转投InnoDB引擎吧&
综上,查询中有Creat sort index就是有问题,可以优化,原语句为&
SELECT FavoriteId, UserId, SourceId, AddTime, Type, SellerId, ProductId&FROM `App_UserFavorite`&WHERE `Userid` =
and `AddTime` & ' 11:42:14.893' order by `FavoriteId` desc limit 10优化为
explain SELECT FavoriteId, UserId, SourceId, AddTime, Type, SellerId, ProductId&FROM `App_UserFavorite`&WHERE `Userid` =
and `AddTime` & ' 11:42:14.893' order by `AddTime` desc limit 10优化后就没有&Creat sort index
3. 查看执行计划&explain示例:&
explain SELECT FavoriteId, UserId, SourceId, AddTime, Type, SellerId, ProductId&FROM `App_UserFavorite`&WHERE `Userid` =
and `AddTime` & ' 11:42:14.893' order by `FavoriteId` desc limit 10
详细Extra:
U U Using filesort
explain SELECT FavoriteId, UserId, SourceId, AddTime, Type, SellerId, ProductId&FROM `App_UserFavorite`&WHERE `Userid` =
and `AddTime` & ' 11:42:14.893' order by `AddTime` desc limit 10;
对比两条语句的执行计划,发现第一条的Extra中用到东西多于第二条语句。&Explain具体分析查看: &&
4.&mysql profile 调试sql
(1) 打开profileset profile onset session profiling=1;(2)执行相关语句,例如 :
SELECT FavoriteId, UserId, SourceId, AddTime, Type, SellerId, ProductId&FROM `App_UserFavorite`&WHERE `Userid` =
and `AddTime` & ' 11:42:14.893' order by `FavoriteId` desc limit 10;
(3)查看profile队列中的语句show profiles
对应的QueryId是28(4)查看具体消耗show profile for query 28; //28为QueryId&
可以看出具体时间消耗
5. 查找慢查询select * from mysql.slow_log &where start_time & &' 16:50:20'&mysql.slow_log中会放所有慢查询语句,所以需要&用start_time筛选下。找到慢查询语句,就可以用3,4的方法分析。6. &SPIN_Lock监控
当mysql的并发大时出现性能瓶颈,应用程序并发从1开始加到100的情况,应用每次请求会从Mysql拿下数据,下图是Mysql服务器的CPU占用状况
可以看到SystemTime的占用很高,这种情况一般是Linux底层_spin_lock过高引起的,这种情况下,一般认为mysql已到瓶颈,增大并发,并不能提高TPS_spin_lock是内核级的自旋锁,每个Mysql process都会申请_spin_lock,具体原理,还有待研究监控_spin_lock方法(1)安装perf工具yum install perf
(2)查看mysql进程号top
(3)监控&perf top -p 3127原文链接:
阅读排行榜CocoaPods 命令
pod init 在新建的项目根目录下运行该命令,为当前项目新建podfile文件。
pod install 下载和配置 podfile里定义的项目依赖(不包括已经下载和配置的项目依赖)。(新建podfile.lock文件)并将每个依赖的版本信息记录在podfile.lock文件中。为项目新建.xcworkspace文件。
pod outdated 列出比podfile.lock文件中记录的版本要新的项目。
pod update [依赖项目名称] 将某个依赖更新到最新版本 直接pod udate就把所有依赖都更新到最新版本。
CocoaPods 使用
使用CocoaPods的项目比不使用的项目多了四个文件:分别为podfile文件、podfile.lock文件、.xcworkspace文件以及一个Pods文件夹。
podfile文件为项目的每个target定义(在不同的iOS版本上运行时)所需要的依赖项目。podfile.lock文件用于记录当前项目每个依赖项目的版本,保证该项目的版本信息不被改变。.xcworkspace文件为使用CocoaPods之后项目的启动文件,记录的所有项目文件之间的关系。Pods文件夹是项目的依赖存放的地方。
在项目中使用CocoaPods的关键在于新建一个profile文件。有了profile文件,其余的使用一句命令就可以自动完成。
1、新建项目并使用CocoaPods
在新建的项目根目录下运行该命令pod init命令。自动会在项目根目录下生成profile文件。至此完成了使用CocoaPods的准备工作。
接下来就是打开profile文件,定义依赖,并且运行pod install命令,就会为项目生成使用上面介绍的podfile.lock文件以及.xcworkspace文件。
2、已有项目使用CocoaPods
手动在项目根目录下新建profile文件,定义相关依赖,然后运行pod install,也会生成上述三个文件。
1、初次使用
初次使用CocoaPods的pod install命令,CocoaPods自身会自动进行初始化。初始化所做的其实就是把github上的整个依赖库下载到本地路径/users/用户名/.cocoapods/repos/master文件夹下。但是在国内是不行的,被墙,也就是会一直卡在CocoaPods set up master repo这句话上不动了,或者过了很久给你报错说unable to install bla bla bla …这时可以上github上下载(地址:),然后把下载到的内容自己复制到这个路径下就好了(或者让其他已经用上CocoaPods的人airdrop过来比下载更快,毕竟文件好大。。)。master下文件结构如图:
上图中,Specs就是整个依赖库。
2、版本控制
podfile.lock文件应该始终参与版本控制。
profile文件的基本语言格式
1、基本格式
为某个target定义依赖的格式
最简单的例子:
target 'MyApp' do
pod 'AFNetworking', '~& 3.0'
pod 'FBSDKCoreKit', '~& 4.9’
继承大do - end之间定义的依赖项目
target 'MyApp' do
pod 'GoogleAnalytics', '~& 3.1'
target 'MyAppTests' do
inherit! :search_paths
pod 'OCMock', '~& 2.0.1'
上面MyAppTests也依赖GoogleAnalytics。
定义多个target共享的依赖项目使用abstract_target
abstract_target 'Shows' do
pod 'ShowsKit'
pod 'Fabric'
target 'ShowsiOS' do
pod 'ShowWebAuth'
target 'ShowsTV' do
pod 'ShowTVAuth'
上面的Shows只是个标识,并不存在这样的target。但在它的do-end之间定义的其他的target会共享这个abstract_target所定义的依赖。
定义项目中所有target都使用的依赖项目
直接不加任何修饰地定义就可以了,如下:
pod 'ShowsKit'
pod 'Fabric'
# Has its own copy of ShowsKit + ShowWebAuth
target 'ShowsiOS' do
pod 'ShowWebAuth'
# Has its own copy of ShowsKit + ShowTVAuth
target 'ShowsTV' do
pod 'ShowTVAuth'
2、项目版本的指定
- 指定某个版本:
pod ‘项目名称’, ‘版本号’
pod 'Objection', '0.9'
给出版本范围
符号&、&=、&、&=都能用,
符号~&用法见如下例子:
'~& 0.1.2'
表示范围为&=0.1.2&&&0.2
表示范围为&=0.1&&&1
3、添加本地项目作为依赖
pod 'Alamofire', :path =& '~/Documents/Alamofire'
以上例子全部来自官网。
Cocoapods常用命令及介绍
CocoapodsCocoaPods 是 iOS 最常用最有名的类库管理工具作为 iOS 程序员,掌握 CocoaPods 的使用是必不可少的基本技能删除源(这个系统自带的不好用)$ sudo gem...
Cocoapods安装及使用
最近项目中在集成视频播放,采用了封装很优秀的开源播放器MobileVLCKit,这里使用的是V2.2.2版本。期间遇到了pods安装相当慢的问题,这里就记录一下cocoapods的安装方法和针对下载速...
CocoaPods的使用教程
转载自:https://www.jianshu.com/p/dfe前言前几天发布我的开源库&最简单方便的iOS轮播开源库:JYCarousel&到Coco...
iOS开发~CocoaPods使用详细说明
iOS开发时,项目中会引用许多第三方库,CocoaPods(https://github.com/CocoaPods/CocoaPods)可以用来方便的统一管理这些第三方库(从一个坑出来,...
看一遍就会的CocoaPods的安装和使用教程
什么是CocoaPods?
CocoaPods是专门为iOS工程提供对第三方库的依赖的管理工具,通过CocoaPods,我们可以更方便地管理每个第三方库的版本,而且不需要我们做太多的配置。直观、集中...
cocoapods基本使用
1.创建新工程
例如要导入SDWebImage
2.搜索cocoapods是否支持要使用的第三方类库pod search SDWebImage
(可以把pod 'SDWebImage', '~&...
cocoaPods的使用总结
cocoaPods的使用过程中的经验总结(1). 常用命令1. cd 路径 //cd之后直接把项目文件夹拖进终端即可2. pod search AFNetworking //搜索3.在使用CocoaP...
关于cocoapods的使用
/*关于cocoapods的使用*/以下操作基于:macOS High Sxcode9.3.1环境亲测&&由于该插件由ruby语言编写,需要Ruby2.0y以上...
cocoaPods安装和使用
CocoaPods是iOS最常用的类库管理工具。类似java使用的maven管理jar包,CocoaPods是用ruby来操作。
1.mac系统已经默认安装好Ruby环境,在终端中输入命令行:rub...
iOS开发-CocoaPods使用详细说明以及解决部分报错
iOS开发时,项目中会引用许多第三方库,CocoaPods(https://github.com/CocoaPods/CocoaPods)可以用来方...
没有更多推荐了,

我要回帖

更多关于 profile意思 的文章

 

随机推荐