当前位置: 首页 > 编程日记 > 正文

用Swift实现一款天气预报APP(三)

这个系列的目录:

用Swift实现一款天气预报APP(一)

用Swift实现一款天气预报APP(二)

用Swift实现一款天气预报APP(三)

通过前面的学习,一个天气预报的APP已经基本可用了。至少可以查看现在当前的天气情况和未来几个小时的天气预报了。但是,还不够完善。如果用户想要知道他要去的地方的天气怎么办。明显我们的APP在目前来说无法满足用户的这个需求。而我们的APP需要获取其他城市的天气却非常的简单。通过查看天气的API,发现只要把城市的名称作为参数就可以获得当地城市的天气预报。API:

api.openweathermap.org/data/2.5/find?q=London&type=like&mode=xml

q=London就是在API中指明地点的参数。但是,从这里也可以单出。这个城市的名称显示是需要英文的,不是“北京”这样的汉字,也就是说在城市列表中显示的是汉字,但是传给API的url使用的时这个城市的英文名称,或者可以说是拼音字母。

在这一篇中,我们主要要实现的功能是切换城市,和刷新天气预报数据。首先在Storyboard中添加一个叫做城市列表的Controller。我们需要在Controller中显示一个城市列表,这里需要用到一个在iOS的开发中很常用的控件:UITableView。添加一个UIViewController之后,拖动一个UITableView到这个ViewController上。这样,在界面上来说就齐全了。

下面,创建代码,选择Source,先在Subclass of选择你的超类为UIViewController,然后命名你的类的名称。这里是"CityListViewController"。最后在语言一项选择Swift。你应该不会选择Objective-C的。如图:

之后一路的Next一直到Done。

很多的教程在讲到UITableView的时候总是喜欢用UITableViewController,这个是对用包含一个UITableView的UIViewController的封装。有的时候,系统封装了过多的东西对于开发者来说并不是什么好事。尤其是开发者单独处理UITableView也不会耗费太多的时间。所以,这里使用的是UIViewController和UITableView的组合。

在你的ViewController文件中添加准备绑定的UITableView对象的属性:

@IBOutlet weak var tableView: UITableView!

之后在Controller里选择之后,在右边栏里选择左数第三个选项,然后在下面的Class里选择你刚刚创建的CityListViewController。一般,在你选择完了

Controller之后,Class下面的Module会自动设定为Current-Swift_Weather。也就是会自动选择你的项目名称。如果没有选择的话,你需要手动添加你的项目名称到Module里。否则,这个ViewController是不可用的。Swift中引入了Module(模块)这个概念。默认的你的APP就是一个Module。类都是从你的应用的Module里查找的。如果没有这个Module名称的话,应用无法找到你给这个ViewController关联的代码。

这些操作完成之后,你已经把Storyboard的ViewController和对应的代码关联在了一起。下面还需要关联上前文提到的UITableView控件。点击你刚刚选中的controller然后在右边栏中选择最右边的箭头按钮你会看到里面会出现一个tableView,他后面的小圆圈还没有和Storyboard的TableView关联起来。鼠标放在小圆圈上,按下Ctrl同时移动鼠标到Storyboard的UITableView上。

到目前为止都很完美,但是这个TableView还不能用。TableView需要知道有多少个TableViewCell要显示出来,每一个Cell上面显示什么内容。每一个Cell有多高,有多少个Section。哪个Cell被选中,哪个Cell从被选中变成了么有被选中等等。。。这些都是通过TableView的代理实现的。这样的代理一共有两个,一个叫做UITableViewDelegate,一个叫做UITableViewDataSource

所以,还需要把UITableView的两个代理和UITableView所在的Controller关联。选中Storyboard的UITableView,然后选择右边栏的最后一个选项。就是最后的那个选项。你会看到

把鼠标放在小圆圈上,同时按下Ctrl键,移动鼠标到这个UITableView所在的Controller上,准确的说是移动到这里:。两个都是这样的操作。完成之后就给这个UITableView关联好了UITableViewDelegateUITableViewDataSource

到目前为止,我们在Storyboard中创建了一个Controller(Scene),在上面放了一个UITableView。创建了一个UIViewController代码,并且和刚刚创建的Controller关联到了一起。并且把UITableView也关联到了一起,同时关联的还有这个UITableView的UITableViewDelegateUITableViewDataSourceUITableViewDelegateUITableViewDataSource在Swift的语法上来说都是protocol,也就是其他的语言,如Java、C#的接口,哪里继承了哪里就要给出实现。既然UITableView的这delegate和datasource都制定在了他所在的Controller上,那么我们代码里的CityListViewController就需要继承UITableViewDelegateUITableViewDataSource并实现这两个protocol。

class CityListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource

下面是UITableViewDelegateUITableViewDataSource中部分必要的方法的实现。注意,这些只是一个UITableView正常显示的必要方法,还有很多的方法暂时没有用到。

第一行,是指定这个UITableView中有多少个section的,section分区,一个section里会包含多个Cell。这里,是只有一个section。

第二行,是指定每一个section里面有多少个Cell的。因为我们只有一个section,所以,有多少个城市可选就有多少个Cell。这个是视不同情况定的。

第三行,初始化每一个Cell。一个Cell长什么样子就由这个方法决定。

第四行,是选中一个Cell后执行的方法。当用户选择了一个Cell的时候,我们需要知道是哪一个,并把这个Cell的城市的英文名称(或者是拼音的字母)发送到主界面中用于获取该城市的天气数据。

这些,就是使用一个UITableView时的全部了。首先创建一个放UITableView的Controller(Scene)然后拖动一个UITableView在上面。二,创建一个对应于这个Scene的Controller的Swift代码,并在代码中添加UITableView属性。关联Scene和Swift的Controller,关联代码的UITableView属性和Storyboard中的UITableView。三,关联UITableView的delegate和datasource到Swift代码的Controller,并在其中继承和实现UITableViewDelegateUITableViewDataSource。这一部分需要多练习并且熟记。因为你会发现没有一个应用不用到UITableView的。如果你找不出UITableView那也可能是开发者对于UITableView的定制比较深,直观上看不出来而已。

这里必须强调的一点,就是第三行的创建Cell的方法。UITableView的Cell不是每次用到都去创建的。手机如今的内存已经有2G的了,CPU也是几核心的。但是,其资源还是相对比较紧缺。如果,每个Cell都新建一个。那么,用户在上下滑动UITableView的时候会非常的卡顿。这对于一个好的APP时绝对不允许的。所以苹果也推荐了一种使用Cell的方法,如果Cell还没有被创建的话就创建一个。如果Cell已经创建了,那么就对这个Cell重新赋值。这里一点很关键,如果一个Cell已经创建了,只重新赋值而不再创建!参见下面的代码:

复制代码
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {var cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier") as? UITableViewCellif cell == nil {cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CellIdentifier")}cell?.textLabel.text = self.cityList.values.array[indexPath.row]return cell!}
复制代码

首先按照Cell的Identifier从UITableView的Cell重用队列获取Cell。如果为空则创建一个Cell,并指定这个Cell的Identifier。如果Cell不为空的话给这个Cell的textLabel的text属性重新赋值。但是,既然我们用了Storyboard了,就用的彻底一点。Cell为什么不用Storyboard来创建呢。这样又会省去很多的代码,比如我们这里的重用Cell的部分。在右边栏中找到UITableViewCell,并拖动到UITableView上。给这个Cell的Identifier起个名字就叫"cityCell"。Style选择Custom,表示我们要自定义这个Cell。如图:

接下来,添加为这个Cell添加新的Swift代码文件。首先,source->Cocoa Touch Class。之后选择

给Cell绑定Swift代码类。选中Storyboard的这里

之后->

这个Cell需要一个UILabel来显示城市的中文名称(这个UILabel只是为了表明在Storyboard中自定义一个Cell的时候该如何处理,一般来说Cell中有一个textLabel可以显示文本)。那么先在代码中添加一个label的属性:

@IBOutlet weak var cityNameLabel: UILabel!

添加完属性之后,关联这cityNameLabel和Storyboard中的Cell中刚刚添加的Label。重复上面说到的第一步,选中这个cell。然后选择第二步中最上面选项中的最后一项。你就会看到cityNameLabel和他后面是小圆圈。你应该知道怎么办了。关联属性和Storyboard的Label之后,回到前面说道的创建Cell的方法。

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {var cityListCell = tableView.dequeueReusableCellWithIdentifier("cityCell", forIndexPath: indexPath) as CityListTableViewCellcityListCell.cityNameLabel.text = self.cityList.values.array[indexPath.row]return cityListCell}

看到有什么不同的么。是的,这里不用再从TableView的Cell的复用队列中获取Cell了。因为,这些都在Storyboard中处理好了。我们只要每次给Cell重新赋值就可以了。

到目前为止,这个城市列表还是不能用的。因为,我们还没有把这个列表和天气预报的主界面关联起来。是的,用户从哪里进入这个城市列表呢。现在我们就把主界面和城市列表关联起来。首先,在Storyboard上拖入一个UINavigationController。删掉后面的RootViewController,并把这个UINavigationControllerRootViewController和我们刚刚创建的城市列表Controller关联起来。这一类似操作在第一部分中讲过。不清楚的话可以重新看看第一部分。

之后,找到主界面的City按钮,连接到新添加的UINavigationController上,在弹出的Action Segue中选择modal。这个时候运行APP,点击City就会出现刚刚创建的CityListController了,用户可以点这上面的某一行,但是。。。回不去了。现在就来处理这个问题。开发这个工作就是“逢山开路,遇水搭桥”。在MainViewController中添加如下代码

    @IBAction func dismissCityListController(segue: UIStoryboardSegue){

        println("dismiss controller")

    }

名字可以任意起,但是参数必须是UIStoryboardSegue类型的。然后,在Storyboard的天气预报主界面中右击Exit,在出现的菜单中你会看到刚刚添加的方法dismissCityListController。在这个方法有个小圆圈。Storyboard里就是充满了这样的小圆圈。把这个小圆圈连接到CityListController的Cell上,在弹出的小菜单中选择selection。也就是说在用户选择了UITableView的一个Cell的时候(selection)CityListController就会“Exit”退出。

这个方法就是传说中的“unwind segue”给这个segue设定一个identifier为“backToMain”。连接好以后再运行APP。在用手指点了一个City以后CityListController就会隐藏起来。用户可以在选择了城市以后返回继续操作。

但是,选择了城市以后主界面显示的还是原来的城市,并没有更换。那时因为,我们并没有添加相关的代码。上面添加的只是让界面可以在segue的引导之下跳转,但是没有更换城市后重新请求天气预报数据。下面就完成这一部分功能。

UIViewController之间传递数据,我们这里是从CityListController传递选择好的城市给MainViewController。方法有很多,比如,以后你会经常用到的Notification的方法。用户选择一个城市之后发出一个Notification,在MainviewController中捕获这个Notification并做相应的处理。看似很简单把。不过我们这里不用这个方法。用Notification的方法会给代码的维护造成一定的困扰。哪里发送,哪里接受都是分开写的,不容易维护代码。我们这里要将的时用代理的方式传递数据。这个中方法在自定义控件,和ViewController之间都会经常用到。具体到我们的天气APP这里,我们需要从CityListController传递数据给MainViewController,那么就在CityListController文件中定义一个接口(protocol)。苹果一般的命名规则是你的Controller的名字后面加Delegate。这样非常好辨认哪里是定义Delegate的,哪里是用到这个Delegate的。

@objc protocol CityListViewControllerDelegate{func cityDidSelected(cityKey: String)
}

这个@objc不是一定要加的,一般是和其他的Objective-C代码共用的时候加。在CityListViewController中添加一个叫做delegate的属性。这个属性会在CityListViewController的UITableView里的某个Cell选中时被执行。

@IBOutlet weak var delegate: CityListViewControllerDelegate?

这里用weak时因为,我们不希望这个代理强引用(strong)其他的Controller。这样会造成循环引用,使得连个Controller的引用计数不减少,从而无法在不用的时候从内存清除。在选中的时候执行

复制代码
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {println("did select row \(indexPath.row)")// set current selected index of city listself.selectedIndex = indexPath.rowif self.selectedIndex != nil && self.delegate != nil {var cityKey = self.cityList.keys.array[self.selectedIndex!]self.delegate?.cityDidSelected(cityKey)}tableView.deselectRowAtIndexPath(indexPath, animated: true)}
复制代码

在CityListViewController中执行代理的方法的话,就需要在MainViewController中实现这个protocol。

复制代码
class MainViewController: UIViewController, CLLocationManagerDelegate, CityListViewControllerDelegate{

//MARK: city changed delegate func cityDidSelected(cityKey: String){println("selected city \(cityKey)")}
}
复制代码

上面的代码是一个大概是实现。具体的代码可以在示例工程中查看。

运行APP,并选择一个其他的城市的时候,这段代码就会执行。在Console中会出现选择的城市的英文名称。现在我们需要来真的了。查看之前的代码,有一个方法func updateWeatherInfo(latitude: CLLocationDegrees, longitude: CLLocationDegrees)会在获取用户的地理位置后请求服务器获得天气预报。我们现在是需要根据城市的名称获取天气预报了。那么,我们就来Over Load方法updateWeatherInfoOver Load就是定义一个和某个别的方法同名但是参数不同的方法。

func updateWeatherInfo(cityName: String)

以后的事情就是在前文中关于HTTP请求的url字符串问题了。这里不多做叙述。

还有一个功能没有完成。你很快会想到:刷新(refresh)。用户在选择了其他的城市的时候,需要很快回到用户点击刷新时所在位置的天气预报。点击Refresh的时候获取用户的最新地理位置数据,并请求天气预报数据。这个功能已经实现。在用户进入主界面的时候就会自动获取用户的位置,并请求天气预报。刷新功能只需要在在refreshAction方法中重新获取用户的地理位置就可以,请求天气预报会在获得用户位置后自动执行。这里需要提到的一点是,当成功获取了天气预报之后,就应该停止获取用户地理位置。因为这样会给用户省电!省电也是用户体验的一部分。作为一个开发者,如果你的APP太多费电,而且还不是一个很好玩的游戏的话实在是说不过去的。

本系列文章的代码在这里。

延伸阅读:AFNetworking是cocoaPods加载进来的。了解更多cocoaPods,请看这里。

本文所使用的代码的原始版本是来自Github的这里。我们现在的代码已经比原作者的丰富的多了。不过还是要感谢原作者。

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!
















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/4151304.html,如需转载请自行联系原作者

相关文章:

asp.net2.0学习历程 菜鸟到中级程序员的飞跃【月儿原创】

asp.net2.0学习历程 菜鸟到中级程序员的飞跃 --30本好书点评 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/ 时间:2007.5.16 学历历程 如果你是一个菜鸟或者自认为初学者那么本文非常适合你; 不能说这30本书…

了解黑客的关键工具---揭开Shellcode的神秘面纱

2019独角兽企业重金招聘Python工程师标准>>> ref: http://zhaisj.blog.51cto.com/219066/61428/ 了解黑客的关键工具---揭开Shellcode的神秘面纱 对于初期接触网络安全的人来说,Shellcode是很神秘的东西,对于网络攻击过程中的嗅探信息、漏洞…

2021年移动云API应用创新开发大赛火热开启!

每一位开发者,都是这个时代宝贵的财富2021年移动云API应用创新开发大赛以“创新云转型,智慧云服务”为主题旨在激发开发者创新动力丰富云计算应用场景与移动云携手探索数智未来给社会带来更多智慧创新体验大赛官方报名通道已开启您可通过下方二维码报名参…

Android 多媒体综述

Android 多媒体综述 多媒体系统是Android中最为庞大的系统,涉及了硬件抽象层、编解码、OpenCore多媒体框架、Android多媒体框架、Java层接口多方面的内容。一、引言本系列内容都是在Android应用层面的,将会分为Camera、Audio、Video三部分进行讲述。另外…

asp.net2.0导出pdf文件完美解决方案【月儿原创】

asp.net2.0导出pdf文件完美解决方案 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/ 时间:2007.5.28 PDF简介:PDF(Portable Document Format)文件格式是Adobe公司开发的电子文件格式。这…

MYSQL 部分事务

MYSQL 中通过 savepoint 的方式来实现只提交事务的一部分。 step 1 : savepoint savepoint_name;、 做标记 step 2 :rollbak to savepoint savepoint_name;回滚到标记点 setp 3 :release savepoint savepoint_name;解除标记 -------------------------------------------------…

二维已经 OUT 了?3DPose 实现三维人体姿态识别真香 | 代码干货

作者|李秋键出品|AI科技大本营(ID:rgznai100)引言人体姿态估计是计算机视觉领域很多研究工作的基础,也是研究的热点问题,在行为识别、人机交互、姿态跟踪等领域有着广泛的应用前景。按照人体姿态维度的差异,可以将人体姿态估计任务分为二维人…

python学习------tab补全

python学习------tab补全 python也可以进行tab键补全 123456789101112131415161718#!/usr/bin/env python# -*- coding: utf-8 -*-# python startup fileimport sys import readline import rlcompleter import atexit import os # tab completionreadline.parse_and_bind(tab:…

asp.net的Ajax学习进阶

asp.net的Ajax学习进阶 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/ 时间:2007.6.3 1.什么是Ajax? 2006年忽如一夜春风来,众多涉及到Web开发的站点都在谈Ajax,那么到底什么是Ajax呢&#xff1f…

Windows下FFmpeg高速入门

本系列文章导航 Windows下FFmpeg高速入门 ffmpeg參数解释 mencoder和ffmpeg參数具体解释(Java处理视频) Java 生成视频缩略图(ffmpeg) 使用ffmpeg进行视频文件转换成FLV整理 java 视频处理 mencoder java 视频处理 ffmpedmencoder Windows下FFmpeg高速入…

“香山”处理器产生背后的逻辑

作者 | 老石谈芯的老石来源 | 老石谈芯在最近召开的RISC-V中国峰会上,中科院计算所的包云岗研究员团队正式发布了名为“香山”的开源高性能RISC-V处理器。前不久我有幸和包老师就这个事情做了一次深度的交流,我们聊了关于RISC-V、还有“香山”处理器的前…

第79天:jQuery事件总结(二)

上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件、事件冒泡和事件移除等内容。 一、合成事件 jQuery有两个合成事件——hover()方法和toggle()方法,同ready()方法一样,这…

asp.net利用RAR实现文件压缩解压缩【月儿原创】

asp.net利用RAR实现文件压缩解压缩 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/ 时间:2007.6.13 如果服务器上安装了RAR程序,那么asp.net可以调用RAR实现文件压缩与解压缩。 不过要注意的是,由…

缺少HTML Doctype造成的样式问题

很简单的一个登陆界面: 代码&#xff1a; <html> <head><style type"text/css">form span {display: block;font-size: 1em;color: #787878;padding-bottom: 5px;font-weight: 600;font-family: Open Sans, sans-serif; }body{background-color: #…

快收藏!整理了 100 个 Python 小技巧

作者&#xff1a;小F来源&#xff1a; 法纳斯特目前Python可以说是非常流行&#xff0c;在目前的编程语言中&#xff0c;Python的抽象程度是最高的&#xff0c;是最接近自然语言的&#xff0c;很容易上手。你可以用它来完成很多任务&#xff0c;比如数据科学、机器学习、Web开发…

--single-transaction 参数对应MyISAM引擎和InnoDB引擎

结论&#xff1a;使用--single-transaction 备份含有MyISAM的表不会获得一致性备份&#xff0c;所有的innodb表可以获得事务开始时的一致性快照&#xff0c;但是MyISAM表获取的是备份该表时的最新快照&#xff0c; 测试库&#xff1a;test&#xff0c;包含表t1,t2,t3,t4,t5,t6 …

C#优化字符串操作【月儿原创】

C#优化字符串操作 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.6.17 开发中可以说几乎随时会涉及到字符串处理&#xff0c;本人觉得很有必要把平时遇到的问题和大家一起讨论&#xff0c;如果大家有好的见解和…

构筑超异构计算时代,英特尔 AI 全布局

作者 | 伍杏玲出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09;我们正值数据井喷时代&#xff0c;据 IDC 发布《数据时代 2025》报告显示&#xff0c;全球每年产生的数据将从 2018 年的 33ZB 增长到 2025 年的 175ZB。其中大部分为非结构化数据&#xff0c;对数据实时…

[软件推荐]电子日记本EDiary,记下您 的每一天

推荐一款电子日记本EDiary&#xff0c;可以记下每天的工作与生活&#xff0c;可支持附件上传&#xff0c;使用方便简单&#xff0c;我从08年开始使用至今&#xff0c;感觉非常不错&#xff0c;也介绍给同事朋友使用&#xff0c;现给大家分享一下。可以到这里下载&#xff1a;ht…

C#的6种常用集合类大比拼【月儿原创】

C#的6种常用集合类大比拼 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.6.27 说明&#xff1a;MSDN没有说出几种集合类其间的区别&#xff0c;当然欲知更多细节可参考MSDN。 一.先来说说数组的不足&#xf…

“35岁才是一个程序员成熟的开始!”

作者 | 王晓波&#xff0c;同程旅行机票事业群CTO【写在前面】不知道从什么时候开始&#xff0c;身边的“小朋友”们都开始为一件事感到焦虑&#xff0c;那就是&#xff1a;“到了35岁我还能找到一份编程的工作吗&#xff1f;”。坦白讲&#xff0c;我年轻的时候也有过迷茫的时…

centos安装easy_instal

easy_install与yum类似&#xff0c;使用easy_install&#xff0c;可以轻松在pypi软件库里面搜索python各类软件安装easy_install比较简单&#xff0c;如果配置好yum&#xff0c;就可以直接搜索python-setuptoolsyum –y install python-setuptools安装完python-setuptools之后&…

如何用xmanager远程连接centos6.0的桌面

在centos6.0系统上设置 修改custom.conf文件 vim /etc/gdm/custom.conf 在[security]下面添加 AllowRemoteRoottrue 在[xdmcp]下面添加 Port177 Enable1 修改完后效果如下&#xff1a; [daemon] [security] AllowRemoteRoottrue [xdmcp] Port177 Enable1 [greeter] [chooser] […

ASP.NET 3.5 企业级开发

议题 .NET Framework 3.5 和Visual Studio 2008 C# 面向对象程序设计 ASP.NET 状态管理和页面传值 ASP.NET 中的错误处理 ADO.NET与数据访问 架构与模式 安全与性能 优秀的团队开发管理功能C# 面向对象程序设计封装继承性多态性抽象类接口装箱和拆箱泛型ASP.NET 状态管理…

DEV报表之条形码

今天无意间发现DEV的报表居然自带条形码生成控件&#xff0c;正好要用到&#xff0c;省的自己手动生成图片了。前提&#xff1a;一张做好的报表Dev报表基础教程首先拖出XRBarCode控件&#xff0c;放到表头的空白位置&#xff0c;摆好高度宽度。选择Symbology&#xff0c;设置你…

Copilot 真会砸了程序员的饭碗?

作者 | 马超 责编 | 孙胜出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;最近OpenAI与GitHub联合构建的AI自动编程工具Copilot正式登场&#xff01;Copilot基于自然语言处理模型GPT-3搭建而成&#xff0c;可在程序员编写代码时提供建议&#xff0c;甚至直接补…

提升城镇化质量 有利于激活智慧城市潜能

国家发展改革委副主任胡祖才指出&#xff0c;智慧城市建设是中国新型城镇化的重要内容&#xff0c;也是推进我国新型城镇化建设的一项长期的任务。如何通过智慧城市建设&#xff0c;促进城市发展模式向资源节约型、环境友好型转变&#xff0c;城市管理由粗放型、经济型向精专化…

变量的属性(全局变量、局部变量、动态变量、静态变量等)

变量的属性 1、变量的分类 l 根据作用域&#xff1a;可分为全局变量和局部变量。 l 根据生存周期&#xff1a;可分为静态存储方式和动态存储方式&#xff0c;具体地又分为自动的&#xff08;auto&#xff09;、静态的&#xff08;static&#xff09;、寄…

Science论文:诺奖经济学家的经典决策模型,被AI挑战

在2019年DOTA2的顶级赛事TI8的正赛完成之后&#xff0c;OpenAI的人工智能战队与TI8的冠军OG举行了一场表演赛&#xff0c;在英雄阵容限定17个&#xff0c;部分道具和功能禁用的前提下&#xff0c;OpenAI以2&#xff1a;0完胜了OG&#xff0c;尤其值得一提的是第二场比赛仅用时1…

Canny算法源码,欢迎交流

http://blog.csdn.net/jianxiong8814/article/details/1563109 http://blog.csdn.net/assuper/article/details/6937130 存在的bug 在dsp http://bbs.csdn.net/topics/390445572