前言

断断续续的已经学习Swift一年多了, 从1.2到现在的2.2, 一直在语法之间徘徊, 学一段时间, 工作一忙, 再捡起来隔段时间又忘了.思来想去, 趁着这两个月加班不是特别多, 就决定用swift仿写一个完整项目.

花田小憩:是一个植物美学生活平台,

以自然生活为主导,

提倡植物学生活方法,

倡导美学标准的生活态度的一个APP.

个人文字功底有限, 就我而言, 这款APP做的挺唯美的…

github地址

https://github.com/SunLiner/Floral

声明

此花田小憩项目里面的都是真实接口, 真实数据, 仅供学习, 毋作其他用途!!!

项目部分截图

由于项目的大体功能都已经实现了的, 所以整个项目还是比较庞大的.所以, 下面罗列部分功能的截图.

由于gif录制的时候, 会重新渲染一遍图片, 所以导致项目中用到高斯模糊的地方, 看起来感觉比较乱, 实际效果还是不错的.

新特性

详情页

更多项目截图请点击原文查看

项目环境

编译器 : Xcode7.3及以上

语言 : Swift2.2

整个项目都是采用纯代码开发模式

tip: 之前编译环境这儿有点错误, 因为我项目中用了Swift2.2的特性, 2.2之后方法名需要写成#selector(AddAddressViewController.save), 不再使用双引号了

第三方框架

use_frameworks!

platform :ios, "8.0"

target 'Floral' do

pod 'SnapKit', '~> 0.20.0' ## 自动布局

pod 'Alamofire', '~> 3.3.1' ## 网络请求, swift版的AFN

pod 'Kingfisher', '~> 2.3.1' ## 轻量级的SDWebImage

end

还用到了MBProgressHUD.

除此之外,几乎全部都是自己造的小轮子…

目录结构详解

Classes下包含7个功能目录:

①Resources : 项目用到的资源,包含plist文件, js文件和字体

②Network : 网络请求, 所有的网络请求都在这里面, 接口和参数都有详细的注释

③Tool : 包含tools(工具类), 3rdLib(第三方:友盟分享, MBProgressHUD ), Category(所有项目用到的分类)

④Home : 首页(专题), 包含专题分类, 详情, 每周Top10, 评论, 分享等等功能模块

⑤Main : UITabBarController, UINavigationController设置以及新特性

⑥Malls : 商城, 包含商城分类, 商品搜索, 详情, 购物车, 购买, 订单, 地址管理, 支付等等功能模块

⑦Profile : 个人中心, 专栏作者, 登录/注册/忘记密码, 设置等功能模块

大家可以下载项目, 对照这个目录结构进行查看, 很典型的MVC文件结构, 还是很方便的.

项目部分功能模块详解

① 新特性NewFeatureViewController : 这个功能模块还是比较简单的, 用到了UICollectionViewController, 然后自己添加了UIPageControl, 只需要监听最后一个cell的点击即可.

这儿有一个注意点是: 我们需要根据版本号来判断是进入新特性界面, 广告页还是首页.

private let SLBundleShortVersionString = "SLBundleShortVersionString"

// MARK: - 判断版本号

private func toNewFeature() -> Bool

{

// 根据版本号来确定是否进入新特性界面

let currentVersion = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String

let oldVersion = NSUserDefaults.standardUserDefaults().objectForKey(SLBundleShortVersionString) ?? ""

// 如果当前的版本号和本地保存的版本比较是降序, 则需要显示新特性

if (currentVersion.compare(oldVersion as! String)) == .OrderedDescending{

// 保存当前的版本

NSUserDefaults.standardUserDefaults().setObject(currentVersion, forKey: SLBundleShortVersionString)

return true

}

return false

}

② 下拉刷新RefreshControl : 在这个项目中, 没有用第三方的下拉刷新控件, 而是自己实现了一个简单的下拉刷新轮子, 然后赋值给UITableViewController的public var refreshControl: UIRefreshControl?属性. 主要原理就是判断下拉时的frame变化:

// 监听frame的变化

addObserver(self, forKeyPath: "frame", options:.New, context: nil)

// 刷新的时候, 不再进行其他操作

private var isLoading = false

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

let y = frame.origin.y

// 1. 最开始一进来的时候, 刷新按钮是隐藏的, y就是-64, 需要先判断掉, y>=0 , 说明刷新控件已经完全缩回去了...

if y >= 0 || y == -64

{

return

}

// 2. 判断是否一进来就进行刷新

if beginAnimFlag && (y == -60.0 || y == -124.0){

if !isLoading {

isLoading = true

animtoringFlag = true

tipView.beginLoadingAnimator()

}

return

}

// 3. 释放已经触发了刷新事件, 如果触发了, 需要进行旋转

if refreshing && !animtoringFlag

{

animtoringFlag = true

tipView.beginLoadingAnimator()

return

}

if y <= -50 && !rotationFlag

{

rotationFlag = true

tipView.rotationRefresh(rotationFlag)

}else if(y > -50 && rotationFlag){

rotationFlag = false

tipView.rotationRefresh(rotationFlag)

}

}

③ 高斯模糊: 使用的是系统自带的高斯模糊控件UIVisualEffectView, 它是@available(iOS 8.0, *), 附一段简单的使用代码

private lazy var blurView : BlurView = {

let blur = BlurView(effect: UIBlurEffect(style: .Light))

blur.categories = self.categories

blur.delegate = self

return blur

}()

可以根据alpha = 0.5, 调整alpha来调整模糊效果, gif图中的高斯模糊效果不是很明显, 实际效果特别好.

④ 商城购物车动画:这组动画还是比较简单的, 直接附代码, 如果有什么疑惑, 可以留言或者私信我

// MARK : - 动画相关懒加载

/// layer

private lazy var animLayer : CALayer = {

let layer = CALayer()

layer.contentsGravity = kCAGravityResizeAspectFill;

layer.bounds = CGRectMake(0, 0, 50, 50);

layer.cornerRadius = CGRectGetHeight(layer.bounds) / 2

layer.masksToBounds = true;

return layer

}()

/// 贝塞尔路径

private lazy var animPath = UIBezierPath()

/// 动画组

private lazy var groupAnim : CAAnimationGroup = {

let animation = CAKeyframeAnimation(keyPath: "position")

animation.path = self.animPath.CGPath

animation.rotationMode = kCAAnimationRotateAuto

let expandAnimation = CABasicAnimation(keyPath: "transform.scale")

expandAnimation.duration = 1

expandAnimation.fromValue = 0.5

expandAnimation.toValue = 2

expandAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)

let narrowAnimation = CABasicAnimation(keyPath: "transform.scale")

// 先执行上面的, 然后再开始

narrowAnimation.beginTime = 1

narrowAnimation.duration = 0.5

narrowAnimation.fromValue = 2

narrowAnimation.toValue = 0.5

narrowAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

let groups = CAAnimationGroup()

groups.animations = [animation,expandAnimation,narrowAnimation]

groups.duration = 1.5

groups.removedOnCompletion = false

groups.fillMode = kCAFillModeForwards

groups.delegate = self

return groups

}()

// MARK: - 点击事件处理

private var num = 0

func gotoShopCar() {

if num >= 99 {

self.showErrorMessage("亲, 企业采购请联系我们客服")

return

}

addtoCar.userInteractionEnabled = false

// 设置layer

// 贝塞尔弧线的起点

animLayer.position = addtoCar.center

layer.addSublayer(animLayer)

// 设置path

animPath.moveToPoint(animLayer.position)

let controlPointX = CGRectGetMaxX(addtoCar.frame) * 0.5

// 弧线, controlPoint基准点, endPoint结束点

animPath.addQuadCurveToPoint(shopCarBtn.center, controlPoint: CGPointMake(controlPointX, -frame.size.height * 5))

// 添加并开始动画

animLayer.addAnimation(groupAnim, forKey: "groups")

}

// MARK: - 动画的代理

// 动画停止的代理

override func animationDidStop(anim: CAAnimation, finished flag: Bool) {

if anim ==  animLayer.animationForKey("groups")!{

animLayer.removeFromSuperlayer()

animLayer.removeAllAnimations()

num += 1

shopCarBtn.num = num

let animation = CATransition()

animation.duration = 0.25

shopCarBtn.layer.addAnimation(animation, forKey: nil)

let shakeAnimation = CABasicAnimation(keyPath: "transform.translation.y")

shakeAnimation.duration = 0.25

shakeAnimation.fromValue = -5

shakeAnimation.toValue = 5

shakeAnimation.autoreverses = true

shopCarBtn.layer .addAnimation(shakeAnimation, forKey: nil)

addtoCar.userInteractionEnabled = true

}

}

⑤ 主题详情页:商城详情页的做法也是差不多的, 不过更简单一点.

关键一点在于, 详情页的展示主要依靠于H5页面. 而我们需要根据webview的高度来确定webviewCell的高度.我的做法是监听UIWebView的webViewDidFinishLoad, 取出webView.scrollView.contentSize.height然后给详情页发送一个通知, 让其刷新界面. 暂时没有想到更好的方法, 如果您有更好的做法, 请务必告诉我, 谢谢…

⑥ UIWebView中图片的点击

第①步: 我们创建一个image.js文件, 代码如下:

//setImage的作用是为页面的中img元素添加onClick事件,即设置点击时调用imageClick

function setImageClick(){

var imgs = document.getElementsByTagName("img");

for (var i=0;i<imgs.length;i++){

var src = imgs[i].src;

imgs[i].setAttribute("onClick","imageClick(src)");

}

document.location = imageurls;

}

//imageClick即图片 onClick时触发的方法,document.location = url;的作用是使调用

//webView: shouldStartLoadWithRequest: navigationType:方法,在该方法中我们真正处理图片的点击

function imageClick(imagesrc){

var url="imageClick::"+imagesrc;

document.location = url;

}

第②步:在UIWebView的代理方法webViewDidFinishLoad中, 加载JS文件, 并给图片绑定绑定点击事件

// 加载js文件

webView.stringByEvaluatingJavaScriptFromString(try! String(contentsOfURL: NSBundle.mainBundle().URLForResource("image", withExtension: "js")!, encoding: NSUTF8StringEncoding))

// 给图片绑定点击事件

webView.stringByEvaluatingJavaScriptFromString("setImageClick()")

第③步:在UIWebView的代理方法-webView:shouldStartLoadWithRequest:navigationType:中判断图片的点击

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {

let urlstr = request.URL?.absoluteString

let components : [String] = urlstr!.componentsSeparatedByString("::")

if (components.count >= 1) {

//判断是不是图片点击

if (components[0] == "imageclick") {

parentViewController?.presentViewController(ImageBrowserViewController(urls: [NSURL(string: components.last!)!], index: NSIndexPath(forItem: 0, inSection: 0)), animated: true, completion: nil)

return false;

}

return true;

}

return true

}

⑦ 登录/注册/忘记密码:

眼尖一点的朋友可能在上面的gif中已经发现, 花田小憩中的登录/注册/忘记密码界面几乎是一样的, 我的做法是用一个控制器LoginViewController来代表登录/注册/忘记密码三个功能模块, 通过两个变量isRegister和isRevPwd来判断是哪个功能, 显示哪些界面, 我们点击注册和忘记密码的时候, 会执行代理方法:

// MARK: - LoginHeaderViewDelegate

func loginHeaderView(loginHeaderView : LoginHeaderView, clickRevpwd pwdBtn: UIButton) {

let login = LoginViewController()

login.isRevPwd = true

navigationController?.pushViewController(login, animated: true)

}

func loginHeaderView(loginHeaderView : LoginHeaderView, clickRegister registerbtn: UIButton) {

let login = LoginViewController()

login.isRegister = true

navigationController?.pushViewController(login, animated: true)

}

⑧ 验证码的倒计时功能

/// 点击"发送验证码"按钮

func clickSafeNum(btn: UIButton) {

var seconds = 10 //倒计时时间

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);

dispatch_source_set_timer(timer,dispatch_walltime(nil, 0),1 * NSEC_PER_SEC, 0); //每秒执行

dispatch_source_set_event_handler(timer) {

if(seconds<=0){ //倒计时结束,关闭

dispatch_source_cancel(timer);

dispatch_async(dispatch_get_main_queue(), {

//设置界面的按钮显示 根据自己需求设置

btn.setTitleColor(UIColor.blackColor(), forState:.Normal)

btn.setTitle("获取验证码", forState:.Normal)

btn.titleLabel?.font = defaultFont14

btn.userInteractionEnabled = true

});

}else{

dispatch_async(dispatch_get_main_queue(), {

UIView.beginAnimations(nil, context: nil)

UIView.setAnimationDuration(1)

})

dispatch_async(dispatch_get_main_queue(), {

//设置界面的按钮显示 根据自己需求设置

UIView.beginAnimations(nil, context: nil)

UIView.setAnimationDuration(1)

btn.setTitleColor(UIColor.orangeColor(), forState:.Normal)

btn.setTitle("\(seconds)秒后重新发送", forState:.Normal)

btn.titleLabel?.font = UIFont.systemFontOfSize(11)

UIView.commitAnimations()

btn.userInteractionEnabled = false

})

seconds -= 1

}

}

dispatch_resume(timer)

}

⑨ 设置模块中给我们评分

这个功能在实际开发中特别常见:

给我们评分

代码如下, 很简单:

UIApplication.sharedApplication().openURL(NSURL(string: "itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=998252000")!)

其中最后的id需要填写你自己的APP在AppStore中的id, 打开iTunes找到你自己的APP或者你想要的APP, 就能查看到id.

tip: 此功能测试的时候, 必须用真机!!!

⑩ 登录状态.

我们可以通过NSHTTPCookieStorage中的NSHTTPCookie来判断登录状态.也可以自定义一个字段来保存. 根据我抓包得知, 花田小憩APP的做法是第一次登录后保存用户名和密码(MD5加密的, 我测试过), 然后每次启动应用程序的时候, 会首先后台自动登录, 然后在进行评论/点赞等操作的时候呢, 参数中会带上用户的id.由于涉及到花田小憩的账号密码的一些隐私, 所以登录/注册模块, 我就没有没有完整的写出来. 有兴趣的朋友可以私信我, 我可以把接口给你, 在此声明: 仅供学习, 毋做伤天害理之事

`tip: 我在AppDelegate.swift中给大家留了一个开关, 可以快速的进行登录状态的切换…

⑩①: 个人/专栏中心:

 

这两个功能是同一个控制器, 是UICollectionViewController而不是UITableViewController

大家对UITableViewController的header应该很熟悉吧, 向上滑动的时候, 会停留在navigationBar的下面, 虽然UICollectionViewController也可以设置header, 但是在iOS9以前, 他是不能直接设置停留的.在iOS9之后, 可以一行代码设置header的停留

sectionHeadersPinToVisibleBounds = true

但是在iOS9之前, 我们需要自己实现这个功能:

//

//  LevitateHeaderFlowLayout.swift

//  Floral

//

//  Created by ALin on 16/5/20.

//  Copyright © 2016年 ALin. All rights reserved.

//  可以让header悬浮的流水布局

import UIKit

class LevitateHeaderFlowLayout: UICollectionViewFlowLayout {

override func prepareLayout() {

super.prepareLayout()

// 即使界面内容没有超过界面大小,也要竖直方向滑动

collectionView?.alwaysBounceVertical = true

// sectionHeader停留

if #available(iOS 9.0, *) {

sectionHeadersPinToVisibleBounds = true

}

}

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

// 1. 获取父类返回的UICollectionViewLayoutAttributes数组

var answer = super.layoutAttributesForElementsInRect(rect)!

// 2. 如果是iOS9.0以上, 直接返回父类的即可. 不用执行下面的操作了. 因为我们直接设置sectionHeadersPinToVisibleBounds = true即可

if #available(iOS 9.0, *) {

return answer

}

// 3. 如果是iOS9.0以下的系统

// 以下代码来源:http://stackoverflow.com/questions/13511733/how-to-make-supplementary-view-float-in-uicollectionview-as-section-headers-do-i%3C/p%3E

// 目的是让collectionview的header可以像tableview的header一样, 可以停留

// 创建一个索引集.(NSIndexSet:唯一的,有序的,无符号整数的集合)

let missingSections = NSMutableIndexSet()

// 遍历, 获取当前屏幕上的所有section

for layoutAttributes in answer {

// 如果是cell类型, 就加入索引集里面

if (layoutAttributes.representedElementCategory == UICollectionElementCategory.Cell) {

missingSections.addIndex(layoutAttributes.indexPath.section)

}

}

// 遍历, 将屏幕中拥有header的section从索引集中移除

for layoutAttributes in answer {

// 如果是header, 移掉所在的数组

if (layoutAttributes.representedElementKind == UICollectionElementKindSectionHeader) {

missingSections .removeIndex(layoutAttributes.indexPath.section)

}

}

// 遍历当前屏幕没有header的索引集

missingSections.enumerateIndexesUsingBlock { (idx, _) in

// 获取section中第一个indexpath

let indexPath = NSIndexPath(forItem: 0, inSection: idx)

// 获取其UICollectionViewLayoutAttributes

let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath)

// 如果有值, 就添加到UICollectionViewLayoutAttributes数组中去

if let _ = layoutAttributes{

answer.append(layoutAttributes!)

}

}

// 遍历UICollectionViewLayoutAttributes数组, 更改header的值

for layoutAttributes in answer {

// 如果是header, 改变其参数

if (layoutAttributes.representedElementKind==UICollectionElementKindSectionHeader) {

// 获取header所在的section

let section = layoutAttributes.indexPath.section

// 获取section中cell总数

let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section)

// 获取第一个item的IndexPath

let firstObjectIndexPath = NSIndexPath(forItem: 0, inSection: section)

// 获取最后一个item的IndexPath

let lastObjectIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section)

// 定义两个变量来保存第一个和最后一个item的layoutAttributes属性

var firstObjectAttrs : UICollectionViewLayoutAttributes

var lastObjectAttrs : UICollectionViewLayoutAttributes

// 如果当前section中cell有值, 直接取出来即可

if (numberOfItemsInSection > 0) {

firstObjectAttrs =

self.layoutAttributesForItemAtIndexPath(firstObjectIndexPath)!

lastObjectAttrs = self.layoutAttributesForItemAtIndexPath(lastObjectIndexPath)!

} else { // 反之, 直接取header和footer的layoutAttributes属性

firstObjectAttrs = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: firstObjectIndexPath)!

lastObjectAttrs = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionFooter, atIndexPath: lastObjectIndexPath)!

}

// 获取当前header的高和origin

let headerHeight = CGRectGetHeight(layoutAttributes.frame)

var origin = layoutAttributes.frame.origin

origin.y = min(// 2. 要保证在即将消失的临界点跟着消失

max( // 1. 需要保证header悬停, 所以取最大值

collectionView!.contentOffset.y  + collectionView!.contentInset.top,

(CGRectGetMinY(firstObjectAttrs.frame) - headerHeight)

),

(CGRectGetMaxY(lastObjectAttrs.frame) - headerHeight)

)

// 默认的层次关系是0. 这儿设置大于0即可.为什么设置成1024呢?因为我们是程序猿...

layoutAttributes.zIndex = 1024

layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size)

}

}

return answer;

}

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {

// 返回true, 表示一旦进行滑动, 就实时调用上面的-layoutAttributesForElementsInRect:方法

return true

}

}

⑩+@end:

 

整个项目, 东西还是蛮多的, 也不是仅仅几百上千字能说清楚的, 几乎每一个页面, 每一个文件, 我都有详细的中文注释. 希望大家一起进步. 这也是我的第一个开源的完整的Swift 项目, 有什么不足或者错误的地方, 希望大家指出来, 万分感激!!!

下载地址

https://github.com/SunLiner/Floral

如果对您有些许帮助, 请☆star

后续

可能有些功能模块存在bug, 后续我都会一一进行修复和完善的, 并更新在github上.

如果您有任何疑问,或者发现bug以及不足的地方, 可以在下面给我留言, 或者关注我的新浪微博, 给我私信.

联系我

https://github.com/SunLiner

iOS 高仿:花田小憩3.0.1的更多相关文章

  1. 《IT蓝豹》高仿花田ios版标签移动效果

    高仿花田ios版标签移动效果,长按每一个item拖动到自己想要位置后,后面位置移动补全效果 . 本项目适合研究gridview拖拽效果的朋友下载. 学习android动画特效. 本项目主要靠DragG ...

  2. iOS高仿app源码:纯代码打造高仿优质《内涵段子》

    iOS高仿app源码:纯代码打造高仿优质<内涵段子>收藏下来 字数1950 阅读4999 评论173 喜欢133 Github 地址 https://github.com/Charlesy ...

  3. iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码

    iOS精选源码 iOS高仿微信完整项目源码 Khala: Swift 编写的iOS/macOS 路由框架 微信左滑删除效果的实现与TableViewCell的常用样式介绍 实现阴影圆角并存,渐变色背景 ...

  4. 仿花田:内部相亲网站 意中人(Asp.net MVC,Bootstrap2)

    起因: 那是七月份了,看见单身的同事在上花田网,当时觉得风格比较清新,还没有世纪佳缘等那些网站那么商业化,加上又看到了bootrstrap,于是就想做个demo出来玩玩.中间自己又在做其他的事情,和w ...

  5. 实例源码--IOS高仿微信打飞机游戏(完整功能)

    下载源码 技术要点: 1. IOS游戏开发基础框架 2. 高仿打飞机游戏 3. 游戏背景音频技术 4.源码详细的中文注释 ……. 详细介绍: 1. IOS游戏开发基础框架 此套源码为涉及IOS游戏开发 ...

  6. iOS高仿微信悬浮窗、忍者小猪游戏、音乐播放器、支付宝、今日头条布局滚动效果等源码

    iOS精选源码 iOS WKWebView的使用源码 模仿apple music 小播放器的交互实现 高仿微信的悬浮小窗口 iOS仿支付宝首页效果 [swift]仿微信悬浮窗 类似于今日头条,网易新闻 ...

  7. iOS高仿城觅应用客户端项目(开发思路和代码)

    这是一款非常完整的一个ios项目,基本实现了我们常用的一些功能了,而且界面设计个人感觉还是挺不错的,是一个不错的学习ios项目,喜欢的朋友可以参考一下吧. 项目展示,由于没有数据,所以所有的cell显 ...

  8. 仿花田:相亲网站 意中人 已在GitHub上开源

    在园友的强烈呼唤下,我还是负责任的分享给大家,因为对代码比较熟悉一下,还是有些问题要说明,不然别人看起来会比较费劲.说实话除了这个bootstrap的界面风格和这件事情本身对大家有吸引力之外,内部的逻 ...

  9. iOS高仿城觅-感谢大神分享

    项目展示,由于没有数据,所以所有的cell显示的都是我自己写的数据 抽屉 首页部分效果 首页效果 部分效果 发现 消息 搜索 设置 模糊效果 代码注释展示 代码注释展示 还有很多细节就不一一展示了,大 ...

随机推荐

  1. sublime3快捷键汇总

    !+tab生成html结构文档选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本.Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子: 快速选 ...

  2. Python处理XML

    在Python(以及其他编程语言)内有两种常见的方法处理XML:SAX(Simple API for XML)和DOM(Document Object Model,文档对象模型).SAX语法分析器读取 ...

  3. Codeforces Round #205 (Div. 2) : A

    题意: 要求找到最少次数的交换次数使得两组数都是偶数: 很明显答案要么是0,要么是1,或者不管怎么交换都不行(-1): 所以: #include<cstdio> #define maxn ...

  4. [置顶] linux内核启动2-setup_arch中的内存初始化(目前分析高端内存)

    上一篇微博留下了这几个函数,现在我们来分析它们         sanity_check_meminfo();         arm_memblock_init(&meminfo, mdes ...

  5. uva 11731 - Ex-circles

    题意:已知三角形ABC的3条边长,求三角形ABC 的面积,以及阴影部分的总面积. #include<iostream> #include<cstdio> #include< ...

  6. Linux Kernel ‘perf’ Utility 本地提权漏洞

    漏洞名称: Linux Kernel ‘perf’ Utility 本地提权漏洞 CNNVD编号: CNNVD-201309-050 发布时间: 2013-09-09 更新时间: 2013-09-09 ...

  7. 使用Redis作为消息队列服务场景应用案例

    一.消息队列场景简介 "消息"是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,"消息队列&qu ...

  8. HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)

    Auxiliary Set Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  9. eclipse常见错误

    1.The superclass “javax.servlet.http.httpservlet” is not found in the build path 原因:未添加server librar ...

  10. 如何优雅的输出PHP调试信息

    经常因为出现紧急bug而被老板骂的同事,为了更快的修复而直接利用线上的错误环境现场debug,并直接在页面上echo和dump.结果被老板发现了,又是一通臭骂.那么有没有什么办法更优雅的输出PHP调试 ...