control your desire when you want to buy something

控制住自己我不知道对别人有多难!

对我很难。。。

如果我想买什么东西,想做什么事情,如果理性的声音告诉我不要这么做,而潜意识的欲望要我这么做的事情,我该怎么办?

延长你的执行时间,立一个理性的FLAG,必须要达成FLAG,再允许自己去实现你的欲望。

TODO:

  • 想买个IPAD PRO 12.9
    • 请先学会swift,上线一个小的APP demo

数组的USAGE-`+`合并数组与array_merge的区别

先上代码:

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
<?php
/**
* 合并数组测试
* + 或 array_merge
*/
$arrMock1 = [
[
'uname' => 'hackingangle',
'age' => 28,
'sex' => 'male',
],
];
$arrMock2 = [
[
'uname' => 'zhangsan',
'age' => 18,
'sex' => 'female',
'asf' => '123'
],
[
'asdf' => 'a',
]
];
$merge1 = (array) $arrMock1 + (array) $arrMock2;
var_dump($merge1);
$merge2 = array_merge($arrMock1, $arrMock2);
var_dump($merge2);

+

如果key相同,则不会覆盖,直接把后面的同名key做舍弃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
array(2) {
[0]=>
array(3) {
["uname"]=>
string(12) "hackingangle"
["age"]=>
int(28)
["sex"]=>
string(4) "male"
}
[1]=>
array(1) {
["asdf"]=>
string(1) "a"
}
}

array_merge

不区分是否key相同,直接进行合并,重新对key进行递增处理

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
array(3) {
[0]=>
array(3) {
["uname"]=>
string(12) "hackingangle"
["age"]=>
int(28)
["sex"]=>
string(4) "male"
}
[1]=>
array(4) {
["uname"]=>
string(8) "zhangsan"
["age"]=>
int(18)
["sex"]=>
string(6) "female"
["asf"]=>
string(3) "123"
}
[2]=>
array(1) {
["asdf"]=>
string(1) "a"
}
}

星星的孩子

摘抄一段星星的孩子的文字:

这个宇宙之中存在另一种现实,存在不同种族的人类,存在更加微妙的世界,只有足够智慧的大脑才能打开那个世界的大门。

From 第一章,阿米的对话(与作者)

作者与阿米的对话,引述出了阿米的观点,对于宇宙的认知,对于世界的理解。
给出了一个更为火爆的观点,更加微妙的世界是存在的,一个普通人是无法感受到的,感受到这个世界的前提条件:足够智慧的大脑
另一种现实也给出了读者一种可能,就是那个世界的组成形式可能不是地球的这种理解的世界。

ios3

今天计算器的小程序完成了,总结一下!

知识点:

  • storyboard使用
    • 为UILabel控件添加置顶的约束
    • 部分网格的动态展开视图
  • ViewController控制逻辑编写
    • 为了功能模块的复用->抽象为方法
    • 匿名方法使用(可以缩略写,利用了类型推断的强大语言特性)
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//
// ViewController.swift
// Cracker
//
// Created by hackingangle on 16/10/2.
// Copyright © 2016年 hackingangle. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
// 定义了当前视图下的label标签的封装对象
// 可以通过在行为中调用此对象来更新对应的标签内容(label.text)
@IBOutlet weak var display: UILabel!
// var isFirstClick = true
var userIsTheMiddleOfTypingANumber = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 接收了点击按钮发送的事件,在这里定义了事件触发时候的行为
// sender是点击按钮的封装,可以通过sender.currentTitle来获取按钮显示的内容
@IBAction func sendNum(_ sender: UIButton) {
let digit:String = sender.currentTitle!
if userIsTheMiddleOfTypingANumber {
// 更新了标签内容
display.text = display.text! + digit
} else {
// 更新标签内容
display.text = digit
userIsTheMiddleOfTypingANumber = true
}
}
@IBAction func clear() {
display.text = "0"
userIsTheMiddleOfTypingANumber = false
numStack = []
}
// v1.1新增:1>计算属性,自动格式化字符串为双精度浮点型;2>设置数据到双精度数组中
// 计算属性,格式化字符串为双精度浮点型
var displayValue:Double {
get {
let fNum:Double = NumberFormatter().number(from: display.text!)!.doubleValue
print("get called")
return fNum
}
set {
print("set called, newValue = \(newValue)")
// 更新label内容
display.text = "\(newValue)"
// 重新计数
userIsTheMiddleOfTypingANumber = false
}
}
// 初始化浮点型数组
var numStack = Array<Double>()
@IBAction func enter() {
// 存储数据到数组
numStack.append(displayValue)
// 重新计数
userIsTheMiddleOfTypingANumber = false
// 输出当前数组
print("numStack is \(numStack)")
}
// +-*/的操作符
@IBAction func operate(_ sender: UIButton) {
if userIsTheMiddleOfTypingANumber {
enter()
}
if let btnValue = sender.currentTitle {
switch btnValue {
case "+":
// performOperation(operation: inc)
// 匿名:最初
performOperation(operation: {(opt1:Double, opt2:Double) in return opt1 + opt2})
case "-":
// performOperation(operation: dec)
// 匿名:通过类型推断,预知参数类型,返回值表达式
performOperation(operation: {(opt1, opt2) in opt1 - opt2})
case "*":
// performOperation(operation: multiply)
// 匿名函数位于调用参数最后一个,可以外置
performOperation(operation: ) {$0 * $1}
case "/":
// performOperation(operation: devide)
// performOperation {$0 / $1}
// 如果参数只有一个匿名函数,则可以直接不带参数
performOperation {$0 / $1}
default:
break
}
} else {
print("click invalid button, newValue")
}
}
// 加减乘除基础方法
func multiply(opA:Double, opB:Double) -> Double {
return opA * opB
}
func devide(opA:Double, opB:Double) -> Double {
return opA / opB
}
func inc(opA:Double, opB:Double) -> Double {
return opA + opB
}
func dec(opA:Double, opB:Double) -> Double {
return opA - opB
}
// 参数声明了方法
func performOperation(operation: (Double, Double) -> Double) {
if numStack.count >= 2 {
displayValue = operation(numStack.removeLast(), numStack.removeLast())
enter()
}
}
// 参数声明了方法, swift3中貌似已经废除
// func performOperation(operation: (Double) -> Double) {
// if numStack.count >= 1 {
// displayValue = operation(numStack.removeLast())
// enter()
// }
// }
}

ios2

我们在ios1基础之上再增强我们的功能,每一次在刷新label显示的同时,完成的是一个数字的录入操作,如果保存录入的数字呢?

我们在swift当中存在各种数据类型,如:数组,字典,集合等,本次我们使用数组就可以完成数据录入后的保存工作,是不是很赞👍!

好吧,先来介绍下数组的简单使用:
声明、初始化、操作

  • 声明、初始化:
      • var arr:[String] = []
      • var arr = [String]()
      • var arr:Array<String> = []
      • var arr = Array<String>()
  • 操作
    • 新增
      • arr.append("hello")

在知道了如何使用数组来缓存数据之后,我们再来学习一个新的概念。
这个概念有点像是JAVA中的setter和getter,也类比与php中的魔术方法setter和getter。
在swift中,我们称之为:可计算属性(computed property),使用方法如下:

1
2
3
4
5
6
7
8
9
var demoValue:String {
set: {
}
get: {
return "Hello,World."
}
}

修改ViewController.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
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
//
// ViewController.swift
// Cracker
//
// Created by hackingangle on 16/10/2.
// Copyright © 2016年 hackingangle. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
// 定义了当前视图下的label标签的封装对象
// 可以通过在行为中调用此对象来更新对应的标签内容(label.text)
@IBOutlet weak var display: UILabel!
var isFirstClick = true
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 接收了点击按钮发送的事件,在这里定义了事件触发时候的行为
// sender是点击按钮的封装,可以通过sender.currentTitle来获取按钮显示的内容
@IBAction func sendNum(_ sender: UIButton) {
if isFirstClick {
// 更新标签内容
display.text = sender.currentTitle!
isFirstClick = false
} else {
// 更新了标签内容
display.text = display.text! + sender.currentTitle!
}
}
@IBAction func clear() {
display.text = "0"
isFirstClick = true
numStack = []
}
// v1.1新增:1>计算属性,自动格式化字符串为双精度浮点型;2>设置数据到双精度数组中
// 计算属性,格式化字符串为双精度浮点型
var displayValue:Double {
get {
let fNum:Double = NumberFormatter().number(from: display.text!)!.doubleValue
print("computed property get called. value is \(fNum)")
return fNum
}
set {}
}
// 初始化浮点型数组
var numStack = Array<Double>()
// 新增加入按钮,把输入的数字缓存起来
@IBAction func enter() {
// 存储数据到数组
numStack.append(displayValue)
// 重新计数
isFirstClick = true
// 输出当前数组
print("numStack is \(numStack)")
}
}

ios1

概述

ios开发除了解决语言(oc,swift)的学习之外,还要了解apple对于ios的N多封装的使用。
ios利用了MVC模型来搭建用户交互行为。
例如本讲所讲,利用storyboard来快速搭建一个UI界面;为UI界面上的按钮来添加点击事件,并且对点击事件的行为进行更新,从而控制视图的显示。
视图的定位在默认的Main.storyboard文件中,利用xcode提供的工具就可以搭建了。

点击事件行为的定义在ViewController.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
//
// ViewController.swift
// Cracker
//
// Created by hackingangle on 16/10/2.
// Copyright © 2016年 hackingangle. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
// 定义了当前视图下的label标签的封装对象
// 可以通过在行为中调用此对象来更新对应的标签内容(label.text)
@IBOutlet weak var display: UILabel!
var isFirstClick = true
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 接收了点击按钮发送的事件,在这里定义了事件触发时候的行为
// sender是点击按钮的封装,可以通过sender.currentTitle来获取按钮显示的内容
@IBAction func sendNum(_ sender: UIButton) {
if isFirstClick {
// 更新标签内容
display.text = sender.currentTitle!
isFirstClick = false
} else {
// 更新了标签内容
display.text = display.text! + sender.currentTitle!
}
}
@IBAction func clear() {
display.text = "0"
isFirstClick = true
}
}

总结

  1. 按钮上可以添加事件
    • 事件可为多个
    • 每个事件都依次会被触发
  2. Controller类的成员变量在App的整个存活周期内都会持有,不会被触发
  3. 成员变量使用,比较php而言,不用this.关键词,直接使用即可
  4. “ALT”按键配合鼠标点击,可以知道Swift类型推断的结果(在不指定类型的情况下)
  5. “CONTROL”按键配合鼠标点击,可以查看API简介
  6. UIButton
    • currentTitle(String?)
  7. UILabel
    • text(String?)
  8. Value Binding技术可以来结包Optional类型
    • demo如下:
      1
      2
      3
      4
      5
      6
      7
      var username:String?= "hackingangle"
      if let username = username
      {
      print("username = \(username)")
      } else {
      print("invalid username")
      }

swift 12

swift中的数组作为强类型,是不允许初始化的时候直接不指定类型的空数组创建的。

因为一切变量,都要求我们必须知道他们的类型,如果声明了一个没有初始化的没有指定类型的空数组,编译器也不知道应该指定什么类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// array and dictionary
var arr = ["hackingangle", "john"]
var arr2:[String] = ["a", "b"]
var arr3:Array<String> = ["c", "d", "e", "f"]
// 类型指定后不能修改,否报错:Cannot assign value of tyoe 'Int' to type 'String'
//arr[0] = 1
arr[0] = "Hello"
// 初始化
var arr4:Array<String> = []
arr4.append("a")
var arr5:[String] = []
arr5.append("b")
var arr6 = Array<String>()
arr6.append("c")
var arr7 = [String]()
arr7.append("d")
// 数组合并
let arr8 = arr4 + arr5 + arr6 + arr7

swift 11

如何去继承使用原来OC中对于字符串操作的方法?

我们只需要引入Foundation就可以了。

我们来介绍下字符串的驼峰化,大写,小写,trim,split,join这些常用的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var str = "hi, hackingangle"
// 驼峰化
str.capitalized
// 大写
str.uppercased()
str.lowercased()
// trim
var str2 = " !!!hi!! "
str2.trimmingCharacters(in: CharacterSet.whitespaces)
str2.trimmingCharacters(in: CharacterSet.init(charactersIn: " !"))
// split
var str3 = "welcome to the swift world."
str3.components(separatedBy: " ")
var str4 = "Welcome to the swift world.NOW-LET-US-START!"
str4.components(separatedBy: CharacterSet.init(charactersIn: " -"))
// join[swift3被废弃了]
var str5 = "-"

swift 10

如何更好的去操作字符串,我们在编写程序的过程中,必须要学习的内容。

字符串常见的操作有:拼接字符串,字符串比较,字符串前缀后缀匹配等

字符串比较要注意:比较的是从第一位开始的asc码表的位置,A<a,a<b,不比较长度。

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
let msg = "Hello,"
let name = "hackingangle"
// 字符串的拼接
let welcome = msg + name
// 比较字符串大小
let str1 = "abc"
let str2 = "abc"
// true
str1 == str2
let str3 = "abd"
// true
str1 < str3
let str4 = "abcd"
// true
str3 > str4
let names = [
"hackingangle",
"john smith",
"lili smith",
"lili zhang",
]
// 直接输出字符串
for name in names {
print("\(name)")
}
// 匹配字符串前缀或者后缀
var countPrefix = 0
var countSubffix = 0
for name in names {
if name.hasPrefix("lili") {
// swift3 废弃了 count++语法
countPrefix += 1
}
if name.hasSuffix("smith") {
countSubffix += 1
}
}