60分钟带你入门iOS开发
本文面向已有其它语言(如Java,C,PHP,Javascript)编程经验的iOS开发初学者,初衷在于让我的同事一小时内了解如何开始开发iOS App,学习目标包括:
- 能使用Xcode IDE、模拟器
- 能修改、调试已有iOS App
- 能在已有应用内创建新模块
- 能创建新应用
- 能发布应用到App Store
本文不包含任何高级的iOS开发知识,已学会iOS开发的同学不要看,看完这篇文章学会了的同学也不用再看了。
不仅是学习一门新语言
初学脚本语言通常不会来绘制图形界面、与人交互,iOS如果不做图形界面,像脚本语言一样处理文本操作数据库,就没啥意思了。
所以,过去我写别的新手入门教程,通常都是写《XXX入门15分钟教程》,而iOS就要花数倍的时间来写了。
iOS开发人群越来越少,说实在的,每次在后台看到一些读者的回应都觉得很欣慰,至少你们依然坚守iOS技术岗…为了感谢读者们,我想把我收藏的一些编程干货贡献给大家,回馈每一个读者,希望能帮到你们。
如果你用得到的话可以直接拿走;如何获取,具体内容请转看-我的GitHub
环境准备
Mac OS
黑苹果
提到iOS开发入门,似乎没办法不说黑苹果。所谓黑苹果,就是把Mac OS改造后安装在非苹果的硬件上,这是违反DMCA法案的,黑苹果的更多资料,可以在维基上找到
苹果电脑价格高,国内软件开发者生存压力大,所以黑苹果在国内也有一些真实的存在,国外当然也有啦。
- 安装黑苹果是非法的
- 个人行为苹果公司一般不会追究,但会遭同行的鄙视
- 黑苹果超级难装,挑硬件。即使完全相同的型号,相同的批次,也有可能A机器装上了,B机器装不上
- 黑苹果系统多少都存在一些使用上的问题,像驱动Bug啦、待机恢复蓝屏啦、上网浏览有问题啦
- 黑苹果不能随意升级,可能升级一次safari就导致整个系统崩溃了
上面这些虽然不会直接影响Xcode写代码、模拟器测试,但写着写着想上网查个东西的时候,safari不能翻页,确实挺影响心情的。所以,钱包允许的前提下,还是搞个苹果电脑省心一些。
Xcode 和 模拟器
从改一个现成的应用开始吧
下载
首先,我们从苹果开发者中心下载一个示例代码回来。我选了ToolBarSearch。
在本文档的末尾,还有一些其它的网址可以下载开源iOS产品或者代码段,但我试了一下,还是Apple Sample Code最容易成功。
打开
双击project文件
打开Finder,进入刚刚下载解压的ToolBarSearch目录,找到ToolBarSearch.Xcodeproj文件,双击之,Xcode会自动启动,并打开这个项目
在Xcode里选择Project打开
在Xcode没启动的情况下(如果Xcode已经启动了,就先按Command Q退出),启动Xcode,会弹出“Welcome to Xcode”的欢迎页,点击左下角的“Open Other”按钮,找到ToolBarSearch目录,双击ToolBarSearch目录,或者双击ToolBarSearch.Xcodeproj文件都可以
如果Xcode处于打开状态,可以点击其菜单栏的File -> Open,或者File -> Open Recent,然后再选择要打开的项目
通过命令行打开
在Mac OS 10.8以前,有些目录(例如/var/private/tmp),在Finder和Xcode的File > Open对话框中,点击鼠标是找不到的,这时候就要通过命令行终端来打开了。
cd /ToolBarSearch的父目录/ToolBarSearch
open -a Xcode
open -a是mac os的系统命令,除了iOS项目,别的项目也可以这样打开。
运行刚下载的应用
点击Xcode左上角的Run按钮(或者同时按下Comman和R键),Xcode会编译源码并在模拟器中运行这个应用。
编译成功会在屏幕上淡淡地显示“Build Succeeded”。反之,失败就显示“Build Failed”且不启动模拟器。
最新的Xcode编译后会报
Compiling IB documents for earlier than iOS7 is no longer supported
, 此时需要手动点击报错,在面板中找到build for 选择合适的版本
修改
在模拟器上看到“Performed search using…”了吧,下面我们改掉它。
在Xcode左上角的Run按钮下方,有一排小按钮,从左到右第三个是一个放大镜图标,鼠标移上去会显示“Show the Search Navigator”,点一下它,打开搜索界面,在它下方出现的Find输入框中输入“performed”
搜索结果只有一条:ToolbarSearchViewController.m,点文件名下方被高亮的“Performed”字串,右侧代码编辑区会自动打开这个文件,并滚动屏幕,使包含“Performed”的这一行出现在编辑区的中间。
修改双引号里的字串,随便改成啥,然后按“Command S”保存。
当然,这些操作,你也可以在终端下通过grep和vim完成。
运行修改后的应用
Objective-C
Objective-C是苹果应用软件(包括苹果电脑上的Mac OS App和移动设备上的iOS App)的开发语言。它是一种面向对象的编程语言。
- 基本上,每一本讲iOS开发的书(纸质书、电子书),都有大量的截图一步一步教如何用IB开发iOS应用,而讲Objective-C开发应用的书却没有那么多。
- IB可以用来直观方便地画界面、设置控件属性、建立代码与控件的联系,但后台的业务逻辑和数据处理仍然要靠Objective-C,可见,不管用不用IB,Objective-C都是绕不过去的。
C的超集
Objective-C扩展了ANSI C,是C的超集,也就是说:
除了面向对象有语法是SmallTalk风格的(下面会讲到),其它非面向对象的语法、数据类型,与C完全相同,所以本文就不再赘述。 来看一个经典的Hello World示例吧:
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]){@autoreleasepool{NSLog(@"Hello World!");}return 0;
}
是不是仿佛穿越回了大一学习C语言的时代,看起来和C几乎没有区别,是吧?是的,因为还没用到它的面向对象特性,哈哈!
SmallTalk的消息传递语法风格
在Java、C++世界,我们调用一个对象的某方法,在Objective-C里,这称作给类型发送一个消息,这可不仅仅是文字游戏,他们的技术细节也是不同的。
[obj undefinedMethod];
在代码里调用没定义的方法(这是Java世界的习惯说法啊,专业的叫法是,给obj对象传递它无法处理的消息),Xcode会警告,但编译能成功,运行的时候会出错。它会输出这样一个错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject undefinedMethod]: unrecognized selector sent to instance 0x8871710'
类似Java的OOP概念
Objective-C中一些面向对象的概念,也可以在Java中找到类似的实现(只能说是类似,不是完全相同),我的读者基本都是Java和PHP程序员,我会在下文中尽量用Java的概念来类比。
GoogleCode上有人整理了Java和Objective-C的概念、数据类型对应表,参见这里
字符串
Objective-C里有字符串是由双引号包裹,并在引号前加一个@符号,例如:
title = @"Hello";
if(title == @"hello") {}
PHP程序员要注意,在这里不能用单引号,即使只有一个字符也不能用。Objective-C与Java、C一样,双引号表示字符串。
函数调用
前文述及,不涉及面向对象时,它和C是完全一样的。以下是几个函数调用的示例:
不带参数
startedBlock();
带参数
NSLog(@"decrypted string: %@", str);
CGRectMake(0,0,0,0);
传递消息给类/实例方法
不带参数
[obj method];
obj.method();
带一个参数:
[counter increase:1];
counter.increase(1);
带多个参数
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue {...} //定义方法
[myObj setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; //调用方法
public void setColorToRedGreenBlue(float red, float green, float blue) {...}
myObj.setColorToRedGreenBlue(1.0, 0.8, 0.2);
消息嵌套
UINavigationBar *bar = [[[UINavigationBar alloc] init] autorelease];
UINavigationBar bar = UINavigationBar.alloc().init().autorelease();//Java没有指针,所以星号去掉了
类
接口和实现
在Objective-C里,和Java的Interface概念相似的是Protocol,下文会讲到。
@interface MyClass {int memberVar1;id memberVar2;
}-(return_type) instance_method1;
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
@implementation MyClass {int memberVar3;
}-(return_type) instance_method1 {....
}
-(return_type) instance_method2: (int) p1 {....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {....
}
@end
接口和实现以@interface、@implementation开头,都以@end结束。“@”符号在Objective-C中是个很神奇的符号。
冒号也是方法名的一部分,method和method:是两个不同的方法名,不是overload,第二个带参数。
public class MyClass {protected int memberVar1;protected pointer memberVar2;private int memberVar3;public (return_type) instance_method1() {....}public (return_type) instance_method2(int p1) {....}public (return_type) instance_method3andPar(int p1, int p2) {....}
}
私有方法和公开方法
写在.h头文件里的方法都是公开的,Objective-C里没有私有方法的概念(没有你说个蛋啊,哈哈哈哈)。
变量和属性
类方法和实例方法
类方法
类方法就是Java、PHP里的Static Method,不用实例化就能调。类方法有一个加号前缀。 示例:
@interface MyClass+(void) sayHello;
@end@implementation MyClass+(void) sayHello {NSLog(@"Hello, World");
}
@end
[MyClass sayHello];
实例方法
实例方法就是Java、PHP里的普通方法,必须实例化才能调。实例方法有一个减号前缀。 示例:
@interface MyClass : NSObject
-(void) sayHello;
@end@implementation MyClass-(void) sayHello {NSLog(@"Hello, World");
}
@end
mycls = [MyClass new];
[mycls sayHello];
Selector
selector就是一个方法指针,类似PHP里的动态方法名:
<?php
class Hello {public function sayHello() {}public function test() {$fun_name = "sayHello";$this->$fun_name();}
}
在Objective-C里,selector主要用来做两类事情:
绑定控件触发的动作
@implementation DemoViewController
- (void)downButtonPressed:(id)sender {//响应“按钮被按下事件”的方法UIButton *button = (UIButton*)sender;[button setSelected:YES];
}- (void)drawAnButton {UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = _frame; btn.tag = 1;btn.backgroundColor = [UIColor clearColor];[btn addTarget: selfaction: @selector(downButtonPressed:)forControlEvents: UIControlEventTouchUpInside];//当这个按钮被按下时,触发downButtonPressed:方法
}
@end
延时异步执行
@implementation ETHotDealViewController
- (void)viewDidLoad {//获取数据源HotDealDataSource *ds = [[HotDealDataSource alloc]init];[ds reload];_items = ds.items;[self performSelector: @selector(refreshTable)withObject: selfafterDelay: 0.5];//延迟0.5秒调用refreshTable方法
}-(void)refreshTable
{[self.tableView reloadData];
}
@end
继承
继承是写在Interface定义里面的。语法为:子类名在左,父类名在右,中间用冒号分隔。 示例:
@interface MyClass : NSObject
@end
public class MyClass extends NSObject {
}
协议(Protocol)
协议的定义
@protocol Printable-(void)print:(NSString)str;
@end
publilc interface Printable {public void print(String str);
}
协议的继承
@protocol Printable <NSObject>-(void)print:(NSString)str;
@end
public interface Printable extends NSObject {public void print (String str);
}
可选方法
@protocol Printable
@optional-(void)print:(NSString)str;
@end
加了@optional关键字,一个类在implements这个协议时,便可以不实现print:方法。
Java里没有类似的实现,除了Collection里会有一些方法带有optional的注释,但Collection是个特例。
协议的实现
一个类实现某些协议是写在Interface定义里面的。语法为:协议名用尖括号包裹,多个协议名用逗号隔开,协议写在父类的右边(如果没有父类就直接写在子类右边)。
@interface MyClass : NSObject <Printable, Drawable>
@end
public class MyClass extends NSObject implements Printable, Drawable {
}
分类(Category)
分类可以给一个已经存在的类增加方法,而不用去改它的源码。Java和PHP中都没有类似的特性。
比如说,NSObject是一个Objective-C内置的系统类,我们想给它增加toJson方法,就像这样:
@interface NSObject (Json)-(NSString)toJson;
@end
@implementation NSObject (Json)-(NSString)toJson {//...}
@end
使用的时候,只要包含NSObject+Json.h,实例化NSObject类,就可以使用toJson方法了:
import "NSObject+Json.h"
@implementation XYZController-(void)test {NSObject *obj = [[NSObject alloc]init];NSString *str = [obj toJson];}
@end
@interface NSObject (Json)-(NSString)toJson;
@end@interface NSObject (XML)-(NSString)toXML;
@end
@implementation NSObject (Json)-(NSString)toJson {//...}
@end@implementation NSObject (XML)-(NSString)toXML {//...}
@end
import "NSObject+Json+XML.h"
@implementation XYZController-(void)test {NSObject *obj = [[NSObject alloc]init];NSString *json = [obj toJson];NSString *xml = [obj toXML];}
@end
Cocoa Touch
最常用设计模式之Delegate
Cocoa Touch大量使用Delegate(委派)设计模式。
常用控件:按钮、文本块、图片、输入框
TableView
WebView
导航条
Xcode
运行
搜索
搜索文本
搜索文件
新建文件/目录
断点
模拟器和真机测试
模拟器测试
在模拟器上操作时,如果执行过程中遇到了你在Xcode里设置的断点,模拟器会暂停运行,并将当前活动窗口切换回Xcode,供你调试。
在Xcode里增加或者取消了断点,不需要重新编译和安装应用即可生效。
切换被模拟的设备
模拟器的“硬件”菜单,可以选择想要模拟什么设备,有iPad、iPhone可选。
切换模拟的iOS版本
在模拟器的“版本”菜单,可以选择要模拟什么版本的iOS。设备和版本是彼此独立的,iPhone 4S可以有5.0,5.1,6.1几种iOS版本,当然了,iPhone 5不可能有4.3的iOS版本。
触摸屏
用鼠标点击(不区分左右键)模拟器上的iPhone、iPad屏幕,就是在模拟用手指触摸iPhone,iPad的屏幕,可以实现一些触摸效果比如:
- 鼠标单击 等于 手指轻触
- 鼠标长按 等于 手指长按(例如你可以在模拟器上长按应用icon调出删除应用的确认框)
- 鼠标按住拖动 等于 手指拖动
- 双击和单击模拟器的Home键也等于双击和单击真机的Home键
多指手势
多指手势比较复杂,在白苹果笔记本上可以模拟简单的双指手势,白苹果的触控板天然支持多指触摸,但要定位到模拟器的区域再响应多指手势就需要借助一些额外的键啦:
输入法和键盘
输入中文
手机上特有的输入法(比如九宫格输入法)不能模拟。模拟器默认的iOS软键盘只有英文输入,在测试应用的时候,我们要用到中文,有两个办法:
- 使用剪贴板,在Mac OS里复制,再到模拟器运行的应用中的输入框上长按鼠标(模拟手指长按)3秒以上,等弹出“粘贴”的时候选择之,即可。
- 在模拟器里,按Home键,找到Setting那个App icon(不是Mac OS顶部的模拟器菜单啊,那里没有Setting的),打开被模拟iOS设备的设置,依次点击”General - Keyboard - International Keyboards - Add New Keyboard…”,加个中文键盘,以后就可以使用被模拟iOS设备软件盘输入中文了,跟在iPhone/iPad真机上一样。
使用Mac电脑的键盘
- 模拟器中的iOS接管了物理键盘输入,所以,调用的是模拟器iOS的输入法,不是你的Mac电脑的输入法。打个比方,你的Mac OS装的是搜狗五笔,模拟器中iOS加了个拼音输入法(Add New Keyboard),那么,在iOS应用中输入中文会调用拼音输入法。
- 要切换模拟器中iOS的中英文输入法,也只能按iOS设备软键盘上的小地球图标,按Mac电脑上的Command+空格键是不行的。
地理位置
摄像头
Mac电脑有摄像头,但Mac OS没有设计API给iOS模拟器调用,所以,不能用模拟器测试对焦闪光灯等功能。
真机测试
将未提交App Store审核通过的应用安装到iOS设备上测试,有三种办法:
- 加入苹果的Developer Program,成为付费会员,有了这个付费会员资格,就可以直接在Xcode中点击”Run”将刚刚改过的代码编译打包安装到开发测试用的iOS设备上。在iOS真机上操作被测试的程序能激活Xcode中设置的断点。
- 越狱iOS设备。将iPhone和iPad越狱后,可以通过SSH直接上传Xcode编译好的ipa包(一个iOS App本质上就是一个ipa包)。
- 越狱的iOS设备,配合破解过的Xcode,甚至可以实现和付费开发者计划一样的功能:在Xcode上点击”Run”,就自动编译安装到iOS设备上去运行了
- 企业部署方案。就像阿里巴巴的轩辕剑一样,用iPhone/iPad访问这个网址,点击里面的轩辕剑链接就可以安装轩辕剑这个应用了。
拥有一个开发者账号
安装证书和私钥
证书
不想看下面各种点击各种页面跳转的直接用浏览器访问证书管理,你要登录你就用Apple ID登录(前提是交过钱,或者找交了钱的人把你加入团队了)。
不嫌烦,或者想知道下次没我这个文档的时候怎么进证书管理吗?按这个步骤操作:
- 进入 苹果开发者中心
- 点击iOS Dev Center
- 点蓝色“Login”按钮,用你的Apple ID登录,登录成功会跳到 开发者首页
- 点击右上角的iOS Provisioning Portal(别找了,直接Command F搜索多好)
- 点左侧菜单栏里的Certificates
双击下载回来的证书,装证书时,会提示你输入密码,这是【钥匙串访问工具】在问你要你的Mac OS账号开机密码(相当于linux里面的sudo),不是Apple ID的密码,不要搞错了。
安装私钥
将设备注册到Provisioning Portal
- 打开Xcode,从Xcode的Window菜单中找到Organizer,打开之(Shift Command 2)。
- 把iOS设备连上电脑,Organizer会自动识别出你的设备,并显示在左侧边栏。
- 在Organizer左侧边栏找到你的设备,右键,点击“Add Device to Provisioning Portal”,然后等Organizer提示你操作成功即可。(选中设备后,右边设备详情区域会显示一个按钮“Use for Development”,点它也可以)。
到iOS真机上运行测试版程序
发布到App Store
打IPA包
IPA包本质上是一个ZIP压缩包,只不过它有着特殊的目录结构,扩展名是ipa,制作方法如下:
- 在Xcode中Build项目,快捷键Command B
- 在左侧项目导航器中,展开Products文件夹,找到你要打包的应用,你的应用名.app,右键,选择show in finder
- 到Finder中Copy这个.app目录(选中,按Command C),复制到一个你新建的名为Payload(区分大小写)的文件夹中
- 找到你的应用Logo,即一个512 * 512像素的PNG文件,copy到与Payload一起(与Payload并列,不要放进Payload了),并重命名为iTunesArtwork(区分大小写,没有扩展名)
- 将Payload目录、ItunesArtwork文件打成一个zip包,并更改扩展名为ipa
- 双击这个ipa文件,会用iTunes打开,如果打开成功,且在iTunes里有应用Logo显示,就成功了
批量自动打包
阅读应用代码
从头新建一个应用:Hello World
其它
代码里的控件尺寸
SVN操作含有@符号的文件
iOS应用中经常出现xxxx@2x.png这样的文件名,它们是给retina设备用的高分辨率大图,用svn命令行操作它们的时候会被@符号干扰,解决方案是在svn命令末尾加上一个@符号,如:
svn del icon@2x.png@
svn info Default@2x.png@
如果一次移动了几十个png文件再svn commit的,可以用shell批处理:
svn status | awk '($1=="!"){print $2}' | grep -v @ | xargs svn del
上面这个命令是将文件名不包含@符号的,且已经不在硬盘上的文件从svn version controll中删掉
for file in `svn status | awk '($1=="!"){print $2}' `; do svn del $file"@"; done
上面这个命令是将文件名包含@符号的,且已经不在硬盘上的文件从svn version controll中删掉
Xcode中的代码结构与操作系统上的文件系统并不一致
推荐在Finder里建好目录再到Xcode的Project Navigator中点击“Add Files to”添加到项目中
iPhone 5适配
iPhone 5与之前的iPhone不一样,采用了4寸Retina屏,所以它的Point数变成了320 * 568 points
开源代码
- Apple官方的Sample Code
- 维基百科上的开源iOS App
- iOS Opensource --Domain Parking了,以前可以下载Twitter和Wordpress客户端的
- code 4 app
- UI 4 app, code4app的姐妹站
Objective-C教程
文章到这里就结束了,感谢你的观看,只是有些话想对读者们说说:
iOS开发人群越来越少,说实在的,每次在后台看到一些读者的回应都觉得很欣慰,至少你们依然坚守iOS技术岗…为了感谢读者们,我想把我收藏的一些编程干货贡献给大家,回馈每一个读者,希望能帮到你们。
干货主要有:
① iOS中高级开发必看的热门书籍(经典必看)
② iOS开发技术进阶教学视频
③ BAT等各个大厂iOS面试真题+答案.PDF文档
④ iOS开发中高级面试"简历制作"指导视频
如果你用得到的话可以直接拿走;如何获取,具体内容请转看-我的GitHub
我的:GitHub地址
60分钟带你入门iOS开发相关推荐
- Android 3分钟带你入门开发测试
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/-TW7p3z3vJ3GJw7X9u7dVg 作者:Zhu Yifei 作为一名合格的开发人员, ...
- swiftUI系列-我的个人side project开始,19年入门iOS开发
swiftUI系列-我的个人side project开始,19年入门iOS开发 我为什么要搞side project 打工是挣钱的最佳途径,但是只是存粹的上班挣钱来说,一是难以获得成就感(毕竟面试造火 ...
- 8分钟带你入门人工智能,互联网大厂都在用的高能AI算法
哈喽,大家好,我是 Jack. 不少小伙伴问我,互联网大厂都在用哪些算法?有哪些算法值得学习? 这次,我做了一个视频,又剪了两周多,速度有点慢,但内容绝对充实. 主要是盘点一些互联网巨头,都在使用的人 ...
- a*算法matlab代码_10分钟带你入门MATLAB
10分钟带你快速入门MATLABhttps://www.zhihu.com/video/1234089282815188992 前一段时间我发现有些小伙伴MATLAB基础比较薄弱,今天我来让各位小 ...
- 15分钟带你入门sklearn与机器学习——分类算法篇
作者 | 何从庆 本文转载自AI算法之心(ID:AIHeartForYou) [导读]众所周知,Scikit-learn(以前称为scikits.learn)是一个用于Python编程语言的免费软件机 ...
- 15 分钟带你入门 sklearn 与机器学习(分类算法篇)
众所周知,Scikit-learn(以前称为scikits.learn)是一个用于Python编程语言的免费软件机器学习库.它具有各种分类,回归和聚类算法,包括支持向量机,随机森林,梯度增强,k-me ...
- Sklearn 损失函数如何应用到_15 分钟带你入门 sklearn 与机器学习(分类算法篇)...
众所周知,Scikit-learn(以前称为scikits.learn)是一个用于Python编程语言的免费软件机器学习库.它具有各种分类,回归和聚类算法,包括支持向量机,随机森林,梯度增强,k-me ...
- 十分钟带汝入门大数据开发语言Scala
大家好,我是百思不得小赵. 创作时间:2022 年 6 月 7 日 博客主页:
- 10分钟带你入门git到github
git的产生背景 很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了.Linus虽然创建了Linux,但Linux的壮大是靠全世界 ...
- JB的Shell之旅-30分钟带你入门
前言 写这篇文章的目的很简单,因为爱并恨过: 前段时间要改个安卓产品的脚本,惊奇发现理论是用shell,虽然实现的功能不复杂,但如果对没了解过shell或懂皮毛的同学,改起来是相当痛苦(如jb),调试 ...
最新文章
- python代码大全和用法用量_Python numpy.stack()用法及代码示例
- Log4j2进阶使用(Pattern Layout详细设置)
- python数据结构实验目的_图的基本操作实现(数据结构实验)
- lwip路由实现_TCP超时与重传《LwIP协议栈源码详解——TCP/IP协议的实现》
- laravel框架常用目录路径
- 马尔科夫过程与吉布斯采样
- 多表查询过滤重复数据_数据分析工具SQL—多表查询
- Excel函数公式大全—VLOOKUP函数
- unzip 分包_劳务派遣第二讲一一劳务派遣和劳务分包有啥区别?
- 使用Python二次开发S3D 查询当前选择元素基本信息
- 沃云的rds数据库修改sql_mode
- 常见的嵌入式操作系统有哪些
- ”我的2016“-太多难忘的第一次
- 麻省理工的服务器位置,麻省理工学院的地理位置是怎样的?
- 当迷茫在大学泛滥成灾 -- 李开复
- ssr_next.js
- 深度学习康耐视ViDi如何添加工具
- 聊天机器人-意图识别类,开源库推荐
- SpringMVC相关面试题
- 华为荣耀+T8950
热门文章
- BT没死!305个国外BT资源聚合站点大全
- 深度装机大师一键重装_deep深度装机大师一键安装Win10 64位旗舰版
- 核爆rpg学院站计算机,《核爆RPG》控制台代码及使用方法
- 谷歌浏览器文件下载了缓存的问题与解决方案
- iPhone6 和iPhone6plus 快速适配
- 【原】iphone6来了,我该做点什么(兼容iphone6的方法)
- 对抗极域电子教室#破解、解除
- mod sim tcp配置_ModSim32-ModScan32Modbus调试工具使用及配置说明
- 【100个 Unity小知识点】☀️ | Unity 可以在编辑器中读取Excel,打包成exe后就无法读取的问题
- 【伸手党福利】开发人员重装系统顺序