Peterfei

上主是我的牧者,我实在一无所缺


  • 首页

  • 归档

  • 标签

swift中的单例

发表于 2016-09-09   |   分类于 Swift   |  

##关于单例
. 单例必须是唯一的,所以它才被称为单例。在一个应用程序的生命周期里,有且只有一个实例存在。单例的存在给我们提供了一个唯一的全局状态。比如我们熟悉的NSNotification,UIApplication和NSUserDefaults都是单例。
. 为了保持一个单例的唯一性,单例的构造器必须是私有的。这防止其他对象也能创建出单例类的实例。感谢所有帮我指出这点的人
. 为了确保单例在应用程序的整个生命周期是唯一的,它就必须是线程安全的。当你一想到并发肯定一阵恶心,简单来说,如果你写单例的方式是错误的,就有可能会有两个线程尝试在同一时间初始化同一个单例,这样你就有潜在的风险得到两个不同的单例。这就意味着我们需要用GCD的dispatch_once来确保初始化单例的代码在运行时只执行一次。

swift 中单例写法

1
2
3
class TheOneAndOnlyKraken {
static let sharedInstance = TheOneAndOnlyKraken()
}

项目中的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class YMNetworkTool: NSObject {
/// 单例
static let shareNetworkTool = YMNetworkTool()
/// 获取首页数据
func loadHomeInfo(id: Int, finished:(homeItems: [YMHomeItem]) -> ()) {
// SVProgressHUD.showWithStatus("正在加载...")
let url = BASE_URL + "v1/channels/" + String(id) + "/items?gender=1&generation=1&limit=20&offset=0"
Alamofire
.request(.GET, url)
.responseJSON { (response) in
guard response.result.isSuccess else {
// SVProgressHUD.showErrorWithStatus("加载失败...")
return
}
if let value = response.result.value {
let dict = JSON(value)
let code = dict["code"].intValue
let message = dict["message"].stringValue
guard code == RETURN_OK else {
// SVProgressHUD.showInfoWithStatus(message)
return
}
// 移除加载提示
// SVProgressHUD.dismiss()
let data = dict["data"].dictionary
// 字典转成模型
if let items = data!["items"]?.arrayObject {
var homeItems = [YMHomeItem]()
for item in items {
let homeItem = YMHomeItem(dict: item as! [String: AnyObject])
homeItems.append(homeItem)
}
finished(homeItems: homeItems)
}
}
}
}
/// 获取首页顶部选择数据
func loadHomeTopData(finished:(ym_channels: [YMChannel]) -> ()) {
let url = BASE_URL + "v2/channels/preset?gender=1&generation=1"
Alamofire
.request(.GET, url)
.responseJSON { (response) in
guard response.result.isSuccess else {
// SVProgressHUD.showErrorWithStatus("加载失败...")
return
}
if let value = response.result.value {
let dict = JSON(value)
let code = dict["code"].intValue
let message = dict["message"].stringValue
guard code == RETURN_OK else {
// SVProgressHUD.showInfoWithStatus(message)
return
}
// SVProgressHUD.dismiss()
let data = dict["data"].dictionary
if let channels = data!["channels"]?.arrayObject {
var ym_channels = [YMChannel]()
for channel in channels {
let ym_channel = YMChannel(dict: channel as! [String: AnyObject])
ym_channels.append(ym_channel)
}
finished(ym_channels: ym_channels)
}
}
}
}
}

IOS swift UITabBarController 开发

发表于 2016-09-09   |   分类于 Swift   |  

Swift 开发中,省去storyboard,应用UITabBarController也可以生成:
效果
首页写AppDelegate.swift:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame:UIScreen.mainScreen().bounds)
window?.rootViewController = YMTabBarController()
window?.makeKeyAndVisible()
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

YMTabBarController.swift:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import UIKit
class YMTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
tabBar.tintColor = UIColor(red: 245 / 255, green: 80 / 255, blue: 83 / 255, alpha: 1.0)
addChildViewControllers()
// Do any additional setup after loading the view.
}
private func addChildViewControllers(){
addChildViewController("YMDanTangViewController", title: "单糖", imageName: "TabBar_home_23x23_")
// addChildViewController("YMProductViewController", title: "单品", imageName: "TabBar_gift_23x23_")
// addChildViewController("YMCategoryViewController", title: "分类", imageName: "TabBar_category_23x23_")
addChildViewController("YMMeViewController", title: "我", imageName: "TabBar_me_boy_23x23_")
}
/**
# 初始化子控制器
- parameter childControllerName: 需要初始化的控制器
- parameter title: 标题
- parameter imageName: 图片名称
*/
private func addChildViewController(childControllerName: String, title: String, imageName: String) {
// 动态获取命名空间
let ns = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! String
// 将字符串转化为类,默认情况下命名空间就是项目名称,但是命名空间可以修改
let cls: AnyClass? = NSClassFromString(ns + "." + childControllerName)
let vcClass = cls as! UIViewController.Type
let vc = vcClass.init()
// 设置对应的数据
vc.tabBarItem.image = UIImage(named: imageName)
vc.tabBarItem.selectedImage = UIImage(named: imageName + "selected")
vc.title = title
// 给每个控制器包装一个导航控制器
let nav = YMNavigationController()
nav.addChildViewController(vc)
addChildViewController(nav)
}
}

这里面有几个知识点:

###如何通过字符串创建类对象

1. 在swift中打印对象时,会发现在类型前面总会有命名空间 .+类名
2. 在swift中用字符串生成类对象就需要拼接成这样的格式,才能成功生成类
3. 注意,命名空间不要加特殊符号,不然依然无法获取控制器类


swift中闭包使用

发表于 2016-09-04   |   分类于 Swift   |  
闭包是自包含的函数代码块,可以在代码中被传递和使用。
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。这就是所谓的闭合并包裹着这些常量和变量,俗称 闭包。Swift 会为您管理在捕获过程中涉及到的所有内存操作。

Swift 的闭包表达式拥有简洁的风格,并鼓励在常见场景中进行语法优化,主要优化如下:

  1. 利用上下文推断参数和返回值类型
  2. 隐式返回单表达式闭包,即单表达式闭包可以省略 return 关键字
  3. 参数名称缩写
  4. 尾随(Trailing)闭包语法

##闭包表达式语法(Closure Expression Syntax)
闭包表达式语法有如下一般形式:

1
2
3
{ (parameters) -> returnType in
statements
}

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@IBAction func operate(sender: UIButton) {
let operate = sender.currentTitle!
print("current operate is \(operate)")
switch operate {
case "+": performOperation({$0+$1})
case "−": performOperation({$1-$0})
case "×": performOperation({$0*$1})
case "÷": performOperation({$1/$0})
default:
break
}
}
func performOperation(operation:(Double, Double) -> Double) {
if operandStack.count>=2 {
displayValue = operation(operandStack.removeLast(),operandStack.removeLast())
print("displayValue is \(displayValue)")
enter()
}
}

Swift 基础语法

发表于 2016-08-20   |   分类于 Swift   |  

##声明常量和变量
let 声明的是常量 var 声明变量
e.g.

1
2
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

多个变量,分隔
var x = 0.0, y = 0.0, z = 0.0

##类型标注
var welcomeMessage: String

注: :后有空格

welcomeMessage变量现在可以被设置成任意字符串:welcomeMessage = "Hello"

常量一经声明就不允许改值,否则编译器报错

同ruby 语法类似 ,swift 在字符串中可这样输出变量||常量
将常量或变量名放入圆括号中,并在开括号前使用反斜杠将其转义

1
print("The current value of friendlyWelcome is \(friendlyWelcome)")

##属性观察器
属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外
可以为属性添加如下的一个或全部观察器:

  1. willSet在新的值被设置之前调用
  2. didSet在新的值被设置之后立即调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps

##泛型函数

1
2
3
4
5
func swapTwoValues<T>(inout a: T, inout _ b: T) {
let temporaryA = a
a = b
b = temporaryA
}

rails page no cache

发表于 2016-08-16   |   分类于 ROR   |  

Rails 页面在完成权限时总是出现加载缓存页,导致加载出admin权限json渲染页。查看了浏览器请求,是页面cache引起,以下是解决方案:

1
2
3
4
5
6
7
before_filter :set_cache_headers
def set_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 2016 00:00:00 GMT"
end

1…678…16
peterfei

peterfei

peterfei|技术|上主是我的牧者

79 日志
14 分类
62 标签
RSS
github
© 2025 peterfei
由 Hexo 强力驱动
主题 - NexT.Mist