Skate Cloud's Blog

^ω^


  • 首页

  • 归档

  • 标签

mac_Automator_link_HUST_WIRELESS

发表于 2018-06-25

手动创造简单的连接校园网方式

第一步

创建python脚本:

1
2
3
4
5
6
7
import requests
import time
time.sleep(5)
str = (requests.get("http://123.123.123.123").text.split('\''))[1]
#在userId里面键入自己的帐号,password里键入密码
postjson = {'userId':'','password':'','service':'','queryString':str,'operatorPwd':'','validcode':''}
r=requests.post('http://192.168.50.3:8080/eportal/InterFace.do?method=login',data=postjson)

保存文件,例如linknet.py,也可以在文件下载地址获取,记得填入帐号和密码😁

打开终端—— 》将linknet.py拖入,控制台会打印出实际路径,例如:/Users/mac/Downloads/linknet.py

那么linknet.py所处的文件夹地址即为/Users/mac/Downloads

第二步

打开automator->新建文稿->应用程序->选取->搜索shell->运行Shell脚本->按住并拖入右边空白/双击->

Command+S存储为linknet.app

最后一步:使用

Control+空格打开Spotlight,输入linknet->点击即可运行

Q&A

运行报错: requests包的问题->配置]参考解决方案

进度缓慢: 如果运行时间过长,很可能是WIRELESS的信号太差了😁,待会儿再跑一次就好了

其他问题: 可以直接联系我Email

post

发表于 2018-06-25

iOS 多线程

发表于 2018-04-15

多线程的基本概念

  • 进程:可以理解成一个运行中的应用程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,主要管理资源。
  • 线程:是进程的基本执行单元,一个进程对应多个线程。
  • 主线程:处理UI,所有更新UI的操作都必须在主线程上执行。不要把耗时操作放在主线程,会卡界面。
  • 多线程:在同一时刻,一个CPU只能处理1条线程,但CPU可以在多条线程之间快速的切换,只要切换的足够快,就造成了多线程一同执行的假象。
  • 线程就像火车的一节车厢,进程则是火车。车厢(线程)离开火车(进程)是无法跑动的,而火车(进程)至少有一节车厢(主线程)。多线程可以看做多个车厢,它的出现是为了提高效率。
  • 多线程是通过提高资源使用率来提高系统总体的效率。
  • 我们运用多线程的目的是:将耗时的操作放在后台执行!

线程的生命周期

  • 新建:实例化线程对象
  • 就绪:向线程对象发送start消息,线程对象被加入可调度线程池等待CPU调度。
  • 运行:CPU 负责调度可调度线程池中线程的执行。线程执行完成之前,状态可能会在就绪和运行之间来回切换。就绪和运行之间的状态变化由CPU负责,程序员不能干预。
  • 阻塞:当满足某个预定条件时,可以使用休眠或锁,阻塞线程执行。sleepForTimeInterval(休眠指定时长),sleepUntilDate(休眠到指定日期),@synchronized(self):(互斥锁)。
  • 死亡:正常死亡,线程执行完毕。非正常死亡,当满足某个条件后,在线程内部中止执行/在主线程中止线程对象

线程安全问题

当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题。就好比几个人在同一时修改同一个表格,造成数据的错乱。

解决多线程安全问题的方法

  • 方法一:互斥锁(同步锁)

判断的时候锁对象要存在,如果代码中只有一个地方需要加锁,大多都使用self作为锁对象,这样可以避免单独再创建一个锁对象。

加了互斥做的代码,当新线程访问时,如果发现其他线程正在执行锁定的代码,新线程就会进入休眠。

  • 方法二:自旋锁

加了自旋锁,当新线程访问代码时,如果发现有其他线程正在锁定代码,新线程会用死循环的方式,一直等待锁定的代码执行完成。相当于不停尝试执行代码,比较消耗性能。

GCD的理解与使用

GCD的特点

  • GCD会自动利用更多的CPU内核
  • GCD自动管理线程的生命周期(创建线程,调度任务,销毁线程等)
  • 程序员只需要告诉 GCD 想要如何执行什么任务,不需要编写任何线程管理代码

GCD的基本概念

  • 任务(block):任务就是将要在线程中执行的代码,将这段代码用block封装好,然后将这个任务添加到指定的执行方式(同步执行和异步执行),等待CPU从队列中取出任务放到对应的线程中执行。
  • 同步(sync):一个接着一个,前一个没有执行完,后面不能执行,不开线程。
  • 异步(async):开启多个新线程,任务同一时间可以一起执行。异步是多线程的代名词
  • 队列:装载线程任务的队形结构。(系统以先进先出的方式调度队列中的任务执行)。在GCD中有两种队列:串行队列和并发队列。
  • 并发队列:线程可以同时一起进行执行。实际上是CPU在多条线程之间快速的切换。(并发功能只有在异步(dispatch_async)函数下才有效)
  • 串行队列:线程只能依次有序的执行。
  • GCD总结:将任务(要在线程中执行的操作block)添加到队列(自己创建或使用全局并发队列),并且指定执行任务的方式(异步dispatch_async,同步dispatch_sync)

队列的创建方法

  • 使用dispatch_queue_create来创建队列对象,传入两个参数,第一个参数表示队列的唯一标识符,可为空。第二个参数用来表示串行队列(DISPATCH_QUEUE_SERIAL)或并发队列(DISPATCH_QUEUE_CONCURRENT)。
  • GCD队列种类:
    • 主队列:主队列负责在主线程上调度任务,如果在主线程上已经有任务正在执行,主队列会等到主线程空闲后再调度任务。通常是返回主线程更新UI的时候使用。dispatch_get_main_queue()
    • 全局并发队列:全局并发队列是就是一个并发队列,是为了让我们更方便的使用多线程。dispatch_get_global_queue(0, 0)

同步/异步/任务

  • 同步(sync)使用dispatch_sync来表示。
  • 异步(async)使用dispatch_async。

GCD的使用

由于有多种队列(串行/并发/主队列)和两种执行方式(同步/异步),所以他们之间可以有多种组合方式。

  • 串行同步
  • 串行异步
  • 并发同步
  • 并发异步
  • 主队列同步
  • 主队列异步

线程通讯

开发中需要在主线程上进行UI的相关操作,通常会把一些耗时的操作放在其他线程,比如说图片文件下载等耗时操作。

当完成了耗时操作之后,需要回到主线程进行UI的处理,这里就用到了线程之间的通讯。

  • 开发中需要在主线程上进行UI的相关操作,通常会把一些耗时的操作放在其他线程,比如说图片文件下载等耗时操作。

    当完成了耗时操作之后,需要回到主线程进行UI的处理,这里就用到了线程之间的通讯。

  • 开发中需要在主线程上进行UI的相关操作,通常会把一些耗时的操作放在其他线程,比如说图片文件下载等耗时操作。

    当完成了耗时操作之后,需要回到主线程进行UI的处理,这里就用到了线程之间的通讯。

advanced swift self conclusion

发表于 2017-12-28
1
2

Alipay-SDK-swift4

发表于 2017-12-24

前言:这个是我做LinkHust的过程中遇到的问题,在这个上面花了挺多时间的,下面就让我们来一步一步的搭建支付功能吧。

我还写了一个小的Demo便于参考,地址:Github 地址

别忘了star呦,嘻嘻

如果还有问题的话可以联系我:baiyun@bingyan.net

first of all

先按官方文档给的,将文件拖入demo,这里要注意,拖入Utils时要记得选择creat group选项

然后要建立桥接文件:

  • 手动建立的话,流程应该是File->New File->header file确定一个名字就可以了,然后在Project->Bulid Settings搜索header,选择OC-Bridging Header,双击,将你的头文件拖进去,就可以了。

效果应该是这样的:

可以看到,Xcode会自动识别你的头文件路径的

按照官方给的demo,header中应该引入头文件:

1
2
3
4
#import <AlipaySDK/AlipaySDK.h>
#import "APAuthInfo.h"
#import "APOrderInfo.h"
#import "APRSASigner.h"
  • 或者可以Xcode为你自动生成头文件,但是我的Xcode9从来没有成功过,我还是选择Manually比较好

这个是拖完的效果

Command+R一下,会发现

Undefined symbols for architecture x86_64:

“_BIO_new”, referenced from:

​ _rsa_sign_with_private_key_pem in openssl_wrapper.o

报错原因是:没有拖入libcrypto.a&libssl.a文件,拖入进去

command+R就build成功了😄

要注意的地方:header中如果找不到文件的话,记得Targets->SearchPaths中加入,为了防止报错,我全加了一遍,可以看一下

second

下面我们要做的就是使用支付宝的功能了呢,踩完了一遍这个坑,现在使用这个SDK居然有些得心应手?喵喵喵?

  • 首先在Appdelegate.swift文件中加入:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    if url.host == "safepay" {
    AlipaySDK.defaultService().processAuthResult(url, standbyCallback: {(resultDic) in
    print(resultDic)
    })
    return true
    }
    return true
    }
    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    if url.host == "safepay" {
    AlipaySDK.defaultService().processAuthResult(url, standbyCallback: {(resultDic) in
    print(resultDic)
    })
    return true
    }
    return true
    }
  • 然后应该是在viewcontroller中加入代码使我们的app可以跟SDK联系起来

    • 在开始coding之前我要提醒一下,不要忘了添加URL Shemes这个可以告诉iOS,在完成支付之后跳回哪个app,具体步骤Targets->Info->URL Types,完成后长这样:

    • 好啦,我们终于可以开始心心念念的coding啦,我在这里按照官方文档给的,直接将app的orderstring放在本地拼接,实际使用中还是要向后台请求的。我们来看一下代码

      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
      @IBAction func clickbutton(_ sender: UIButton) {
      var orderString = ""
      let rsa2PrivateKey = "" //私钥rsa2格式,这里可以二者选一(rsa2或者rsa),但是官方建议是选择rsa2
      //拼接过程
      let appId = "" //公司申请的支付宝appid
      let order = APOrderInfo()
      order.app_id = appId
      order.method = "alipay.trade.app.pay"
      order.charset = "utf-8"
      order.notify_url = "" //请求结果,填入后台地址,阿里会异步通知后台
      let dateFormatter = DateFormatter()
      dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
      order.timestamp = dateFormatter.string(from: Date())
      order.version = "1.0"
      order.sign_type = "RSA2"
      //商品数据
      order.biz_content = APBizContent()
      order.biz_content.body = "测试" //自定订单内容,这个其实在使用的时候看不出来
      order.biz_content.subject = "LinkHust联网费用" //自定订单title,这个要记得说明这项费用的明目
      order.biz_content.out_trade_no = "0000134"//自己定id,记得id不可重复哦
      order.biz_content.timeout_express = "30m"
      order.biz_content.total_amount = "0.01" //价格,测试的话记得改成一分钱,我这次测试才花了几毛钱哈哈哈
      //以下将商品信息拼成string
      let orderInfo = order.orderInfoEncoded(false)
      let orderInfoEncoded = order.orderInfoEncoded(true)
      let signer = APRSASigner(privateKey: rsa2PrivateKey)
      let signString = signer?.sign(orderInfo, withRSA2: true)
      if let signString = signString ,let orderInfoEncoded = orderInfoEncoded{
      let appScheme = "BYshemes" //避免使用 alipay
      orderString = String.init(format: "%@&sign=%@",orderInfoEncoded,signString)
      AlipaySDK.defaultService().payOrder(orderString, fromScheme: appScheme, callback: { (resultDic) in
      print(resultDic)
      });
      }
      }

    end

    我们来测试一下吧

    rsa_private read error : private key is NULL遇到了这样的错误,不要方,It’s fine

    在RSADataSigner.m文件中 搜索代码 [result appendString:@”—–BEGIN PRIVATE KEY—–\n”]; 将其改成 [result appendString:@”—–BEGIN RSA PRIVATE KEY—–\n”];

    在RSADataSigner.m文件中 搜索代码 [result appendString:@”\n—–END PRIVATE KEY—–”]; 将其改成 [result appendString:@”\n—–END RSA PRIVATE KEY—–”];就OK了

    来看一下结果吧:

    结语

    不要怕,支付宝的SDK已经比微信好很多了哈哈,just enjoy it

算法导论-笔记

发表于 2017-12-18
  • 插入排序 𝛩(n^2)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    func insertsort(arr :inout [Int]) -> Void {
    var temp = 0
    var i = 0, j = 0
    for i in 1..<arr.count {
    temp = arr[i]
    for j in (1...i).reversed() {
    if arr[j-1] > temp {
    arr[j] = arr[j-1]
    }
    }
    arr[j] = temp
    }
    }
  • 归并排序 𝛩(nlgn)

    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
    func merge_sort(arr: inout [Int],result: inout [Int],start : Int,end : Int) {
    if start >= end { return }
    let len = end - start, mid = start + len / 2
    var start1 = start, end1 = mid, start2 = mid + 1, end2 = end
    merge_sort(arr: &arr, result: &result, start: start1, end: end1)
    merge_sort(arr: &arr, result: &result, start: start2, end: end2)
    var k = start
    while start1 <= end1 && start2 <= end2 {
    if arr[start1] < arr[start2] {
    result[k] = arr[start1]
    k += 1
    start1 += 1
    } else {
    result[k] = arr[start2]
    k += 1
    start2 += 1
    }
    }
    while start1 <= end1 {
    result[k] = arr[start1]
    k += 1
    start1 += 1
    }
    while start2 <= end2 {
    result[k] = arr[start2]
    k += 1
    start2 += 1
    }
    for k in start...end {
    arr[k] = result[k]
    }
    }

分治策略

在分治策略中,我们递归的求解一个问题,在每层递归中应用如下三个步骤:

  • 分解将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小
  • 解决步骤递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解
  • 合并步骤将子问题的解组合成原问题的解

当子问题足够大,需要递归求解 时,我们称之为递归情况,当子问题变得足够小,不再需要递归时,我们说递归已经“触底”,进入了基本情况

  • 最大子数组问题
    之前在leetcode上做过类似的题,因此贴上来。

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Example 1:
Input: [7, 1, 5, 3, 6, 4]
Output: 5
max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)

Example 2:
Input: [7, 6, 4, 3, 1]
Output: 0
In this case, no transaction is done, i.e. max profit = 0.

1
2
3
4
5
6
7
8
9
10
func maxProfit(prices : [Int])->Int {
var maxprofit = 0
for i in 0..<prices.count-1 {
for j in i+1..<prices.count {
var profit = prices[j] - prices[i]
maxprofit = profit > maxprofit ? profit : maxprofit
}
}
return maxprofit
}

1
2
3
4
5
6
7
8
9
10
11
func maxProfit(prices : [Int])->Int {
var minprice = Int.max, maxprofit = 0
for i in 0..<prices.count {
if prices[i] < minprice {
minprice = prices[i]
} else if prices[i] - minprice > maxprofit {
maxprofit = prices[i] - minprice
}
}
return maxprofit
}

learn-swift-standard-libray

发表于 2017-11-06
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
// debugDescription
struct test {
}
extension test : CustomDebugStringConvertible{
var debugDescription: String {
return "test"
}
}
let tests = test()
debugPrint(tests)
// map , filter , reduce
let a = [1,2,3,4,5,6]
let b = a.filter{$0>3}
let c = a.filter{$0>3}.map{$0*2}
let d = a.filter{$0>3}.map{$0*2}.reduce(0){$0+$1}
print(b,c,d) // [4, 5, 6] [8, 10, 12] 30
//sort
let a = [1,6,2,7,4,3,3]
let test = a.sorted()
let test_1 = a.sorted(by: {$0>$1})
print(test, test_1) // [1, 2, 3, 3, 4, 6, 7] [7, 6, 4, 3, 3, 2, 1]
let test = [-1,-2,-3,0,5,6,7]
let index:Int? = test.index(where: {$0>=0}) // Optional(3)
let test_1 = test.map{$0>0} // [false, false, false, false, true, true, true]
let test_2 = test.filter{$0>0} // [5, 6, 7]
if let i = test.index(of: 3) {
test[i] // 5
}
if let i = test.index(of: 3) {
test[i] //
}
// DateFormatter()
let dateFormatter = DateFormatter()
dateFormatter.doesRelativeDateFormatting = true
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
let date = Date()
dateFormatter.string(from: date)
// slice
let test = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
let testSlice = test[3...7] // [40, 50, 60, 70, 80]
let testSlice_suffix = test.suffix(5) // [60, 70, 80, 90, 100]
let testSlice_prefix = test.prefix(5) // [10, 20, 30, 40, 50]
let str = "hello,there"
let range : ClosedRange<String.Index> = str.index(str.startIndex, offsetBy: 2)...str.index(str.startIndex, offsetBy: 5)
print(str[range]) // llo,

python学习笔记

发表于 2017-10-29

Strings

  • 不想要特殊的符号时,可以在string前加上r
1
2
3
4
5
>>> print('C:\some\name') # here \n means newline!
C:\some
ame
>>> print(r'C:\some\name') # note the r before the quote
C:\some\name
  • 分割长字符串成若干个短字符串
1
2
3
4
5
6
7
>>> test = (
'hello '
'world '
'test'
)
print(test)
>>> hello world test
  • 访问string的元素(索引可以是负数,此时代表从右边开始,倒序,左边最开始为0,所以右边是-1,但是最多只能访问到-string.size)
1
2
3
4
5
>>> word = 'Python'
>>> word[0] # character in position 0
'P'
>>> word[5] # character in position 5
'n'
  • 序列slice被用来获取子字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> word[0:2] # characters from position 0 (included) to 2 (excluded)
'Py'
>>> word[2:5] # characters from position 2 (included) to 5 (excluded)
'tho'
>>> word[:2] + word[2:]
'Python'
>>> word[:4] + word[4:]
'Python'
>>> word[:2] # character from the beginning to position 2 (excluded)
'Py'
>>> word[4:] # characters from position 4 (included) to the end
'on'
>>> word[-2:] # characters from the second-last (included) to the end
'on'

Lists

list 是可变的,有别与string

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
# 访问
>>> squares[0] # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:] # slicing returns a new list
[9, 16, 25]
>>> squares[:]
[1, 4, 9, 16, 25]
# 增加
>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> cubes.append(7 ** 3) # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]
# 修改
>>> cubes = [1, 8, 27, 65, 125]
>>> cubes[3] = 64
>>> cubes
[1, 8, 27, 64, 125]
# replace
>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]
# 获取长度
>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4
# list[list]
>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'

if

1
2
3
4
5
6
7
8
9
10
11
x = input("please input an string: ")
if 3 > len(x) > 0 :
print(">0")
elif 3 < len(x) < 5 :
print('3<x<5')
elif 5 < len(x) < 7 :
print('5<x<7')
else :
print('none')
# please input an string: helloe
# 5<x<7

for

  • for循环与swift中的很相似,采用for…in…遍历list
1
2
3
words = ['hello','how','are','u']
for word in words :
print(word,len(word))

tip:range()函数

1
2
3
4
5
for i in range(5):
print(i) # 01234
range(5,10) # 5,6,7,9
range(0,10,3) # 0,3,6,9
range(-10,-40,-70) # -10,-40,-70

break

break和C语言类似,用于跳出最近一级for或while循环,与循环一起使用时,else 子句与 try 语句的 else 子句比与 if 语句的具有更多的共同点:try 语句的 else 子句在未出现异常时运行,循环的 else 子句在未出现 break 时运行.continue表示循环继续执行下一次迭代(即没有continue不会执行后面的操作)

tips:pass,continue,break区别

先来看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for num in range(0, 5):
if num % 2 == 0:
print(num)
print('none')
print()
for num in range(0, 5):
if num % 2 == 0:
print(num)
pass
print('pass')
print()
for num in range(0,5):
if num % 2 == 0:
print(num)
continue
print('continue')
print()
for num in range(0,5):
if num % 2 == 0:
print(num)
break
print('break')
print()

输出:

0
none
none
2
none
none
4
none

0
pass
pass
2
pass
pass
4
pass

0
continue
2
continue
4

0

不难看出,pass相当于空语句,直接执行if后面的语句,而continue则是直接继续下一个循环,break则是跳出当前循环,自然不会执行print语句

Stack & Queue

  • Stack

    list可以用来构造堆栈

    操作:append() & pop()

  • queue

    list可以用来构造队列,但是效率低。使用collections.deque,它为在首尾两端快速插入和删除而设计

    操作:append() & popleft()

嵌套的列表推导式

1
2
3
4
5
6
7
8
9
10
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
test = list(zip(*matrix)) # [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
test = [[row[i] for row in matrix] for i in range(4)]
# 等价与:
test = []
for i in range(4):
test_row = []
for row in matrix:
test_row.append(row[i])
test.append(test_row)

Set( 集合)

set是一个无序不重复元素的集。集合对象还支持 union(联合),intersection(交),difference(差)和 sysmmetric difference(对称差集)等数学运算。

大括号或 set()函数可以用来创建集合。注意:想要创建空集合,你必须使用 set() 而不是 {}后者用于创建空字典。

1
2
3
4
5
6
7
8
9
10
11
12
a = {'abcdeabcd'} # {'abcdeabcd'}
b = set('abcdeabcd') # {'b', 'c', 'e', 'a', 'd'}
>>> test_a = {'a','b','c','d','e','g'}
>>> test_b = {'e','g','h','i','j'}
>>> test_a - test_b # a除去b中也有的元素
set(['a', 'c', 'b', 'd'])
>>> test_a | test_b # a与b的合集
set(['a', 'c', 'b', 'e', 'd', 'g', 'i', 'h', 'j'])
>>> test_a & test_b # a与b的交集
set(['e', 'g'])
>>> test_a ^ test_b # a与b的合集除去交集
set(['a', 'c', 'b', 'd', 'i', 'h', 'j'])

字典

1
2
3
4
5
6
7
8
9
10
11
12
test = {'a':1,'b':2,'c':3}
test['a'] = 3 # {'a': 3, 'b': 2, 'c': 3}
del test['a']
test['d'] = 4 # {'b': 2, 'c': 3, 'd': 4}
list(test.keys()) # ['b', 'c', 'd']
list(test.values()) # [2, 3, 4]
'a' in test # False
test = dict([('a',1),('b',2),('c',3),('d',4 # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# 字典推导式
test = {x: x**2 for x in (2,4,6)} # {2: 4, 4: 16, 6: 36}
# 如果关键字都是简单的字符串,有时通过关键字参数指定 key-value 对更为方便:
test = dict(a=1,b=2,c=3) # {'a': 1, 'c': 3, 'b': 2}

swift4.0_Self_Conclusion

发表于 2017-07-05
  • String

    Swift的String类型是值类型。如果创建一个新String值,则该String值在传递给函数或方法时被复制,或者当被赋值给常量或变量时被复制。在每种情况下,将String创建现有值的新副本,并且新副本被传递或分配,而不是原始版本。

    Swift的编译器优化了字符串使用情况,以便仅在绝对必要时进行实际复制,这意味着当使用字符串作为值类型时,总是获得很好的性能。

  • index

    每个String值都有一个相关联的索引类型,String.Index它与每个Character字符串的位置相对应。使用startIndex属性访问Charactera 的第一个的位置String。该endIndex属性是最后一个字符之后的位置String。因此,该endIndex属性不是字符串下标的有效参数。如果a String是空的,startIndex并且endIndex是相等的。

  • 集合类型

    Swift提供三种主要的集合类型:数组,集合,字典

  • String:一个阵列存储在有序列表中的相同类型的值。相同的值可以在不同位置多次出现在数组中
  • Set:集合中没有定义顺序,集合中存储相同类型的不同值。当项目的顺序不重要时,或者当您需要确保一个项目只出现一次时,可以使用集合而不是数组。
  • Dictionary:字典存储相同类型的key和value,没有顺序,每个value与唯一的key关联。
  • 控制流

    stride(from:to:by:)功能跳过不需要的标记。(右区间开)

1
2
3
4
for i in stride(from: 1, to: 5, by: 2){
print(i)
}
// 1 3

stride(from:through:by:)(闭合区间)

1
2
3
4
for i in stride(from: 1, through: 5, by: 2){
print(i)
}
// 1 3 5

fallthrough

switch中,当匹配到一个case时,程序就不会往下执行,因此用fallthrough关键字进行下一个匹配

1
2
3
4
5
6
7
8
9
10
11
let a = 4
var s = String()
switch a {
case 4:
s = "a = 4"
fallthrough
default:
print(s + " and a is Int")
}
//a = 4 and a is Int
  • 检查API可用性

    1
    2
    3
    4
    5
    if #available(platform name version, ..., *) {
    statements to execute if the APIs are available
    } else {
    fallback statements to execute if the APIs are unavailable
    }
  • 递归枚举

    关键字:indirect

  • 类和结构体

    共同之处:

    1.定义属性以存储值
    2.定义提供功能的方法
    3.定义下标使用下标语法提供对其值的访问
    4.定义初始化器以设置其初始状态
    5.扩展到扩展其功能超出默认实现
    6.符合协议提供某种特定的标准功能
    

    类的附加功能:

    1.继承使一个类能够继承另一个类的特征。
    2.类型转换使您能够在运行时检查和解释类实例的类型。
    3.取消初始化使类的实例可以释放其分配的任何资源。
    4.引用计数允许多个对类实例的引用。
    

    类是引用类型:
    与值类型不同,当引用类型被分配给变量或常量或将其传递给函数时,不会复制引用类型。而不是复制,而是使用对同一个现有实例的引用

Cocoa框架

发表于 2017-06-24
  • 应用程序
    应用程序实际上就是文件夹,其中包含了编译后的二进制文件以及它们可能需要的所有资源

    在Xcode中编译一个项目并生成应用程序时,Xcode会创建应用程序包,并向其中复制所有必要的资源。

  • 框架
    框架就是可以加载的代码和资源包,可供其他应用程序使用,框架不是独立的,它们被设计来供其他App使用
  • App的构成
    iOS 或 OS X上的应用程序至少包含两项:
    1.编译后的二进制文件
    2.一个用于向系统描述该App的信息文件
12
Skate Cloud

Skate Cloud

hi,这里是记录我学习还有一些思考的地方,欢迎您的访问(-_^)

19 日志
8 标签
© 2018 Skate Cloud
由 Hexo 强力驱动
主题 - NexT.Mist