import Foundation
import PlaygroundSupport
// 1. 关联类型
// 协义只能使用关联类型,不能使用泛型
protocol Container {
associatedtype itemType //:Equatable //可以指定关联 类型符号的约束
mutating func append(_ item: itemType)
var count :Int {get}
subscript(i:Int) -> itemType {get}
// associatedtype Iterator:IteratorProtocol where Iterator.Element == itemType
// func makeIterator()->Iterator
}
// 让关联类型的协义遵循自身
protocol SuffixableContainer:Container {
associatedtype Suffix:SuffixableContainer where Suffix.itemType == itemType
}
struct IntStack: Container {
var items = [Int]()
typealias ItemType = Int // 可以省略,可以自己推断
mutating func append(_ item: itemType) {items.append(item) }
var count: Int { return items.count }
subscript(i:Int) ->ItemType {return items[i]}
}
//var intStack = IntStack()
//intStack.append(1)
//intStack.append(2)
//print(intStack.count)
//print(intStack[0])
func allItemsMatch<C1:Container,C2:Container>(container:C1,anotherContainer:C2) -> Bool where C1.itemType == C2.itemType, C1.itemType : Equatable {
if container.count != anotherContainer.count {
return false
}
for i in 0..<container.count {
if container[i] != anotherContainer[i] {
return false
}
}
return true
}
//var intStack = IntStack()
//intStack.append(1)
//var intStack1 = IntStack()
//intStack1.append(2)
//print(allItemsMatch(container:intStack,anotherContainer:intStack1))
// 泛型下标
extension Container {
subscript<Indices:Sequence>(indices:Indices) -> [itemType] where Indices.Iterator.Element == Int {
var result = [itemType]()
for index in indices {
result.append(self[index])
}
return result
}
}
//var intStack = IntStack()
//intStack.append(1)
//intStack.append(2)
// [(0,0),(0,1),(1,0),(1,1)]
// print(intStack[[0,0]],intStack[[0,1]],intStack[[1,0]],intStack[[1,1]])
//print( intStack[["2","0"]])//error: 75-111.xcplaygroundpage:66:17: error: cannot convert value of type '[String]' to expected argument type 'Int'
//2.thread
//在主线程执行完,线程不退出
PlaygroundPage.current.needsIndefiniteExecution = true
//for i in 0..<10 {Thread.detachNewThread { print(i)}}
class ObjectThread {
func runThread() {
let thread = Thread(target: self, selector: #selector(threadWorker), object: nil)
thread.start()
}
@objc func threadWorker(){print("threadWorker")}
}
//let obj = ObjectThread()
//obj.runThread()
class MyOperation:Operation {
override func main(){
sleep(1)
print("in Myoperation main")
}
}
class ObjectOperation {
func test() {
// let operation = BlockOperation { [weak self] in
// self?.threadWorker()
// }
let operation = MyOperation();
operation.completionBlock = {() -> Void in
print("completionBlock")
}
let queue = OperationQueue()
queue.addOperation(operation)
}
@objc func threadWorker(){sleep(1);print("threadWorker")}
}
//let op = ObjectOperation()
//op.test()
//print("after invoke test")
//3.GCD https://opensource.apple.com/tarbals/libdispatch/
let queue = DispatchQueue(label: "MyQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
let queue2 = DispatchQueue(label: "MyQueue2", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
let arrayQueue = DispatchQueue(label: "MyQueue3", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
queue.sync {print("in DispatchSyncQueue")}
queue.async {sleep(1) ;print("in DispatchAsyncQueue")}
queue.asyncAfter(deadline: .now() + 1) { print("in asyncAfter")}
print("after invoke DispatchQueue")
let group = DispatchGroup()
group.enter()
queue.async { sleep(2); print("A data to req...");group.leave()}
group.enter()
queue.async { sleep(1);print("B data to req..."); group.leave()}
print("group call...")
//group.wait() //block the data
group.notify(queue: queue) { print("merge the data")}
print("no block the data")
var seconds = 10
let timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
timer.schedule(deadline: .now(), repeating: 1.0)
timer.setEventHandler {
seconds -= 1
if seconds < 0 { timer.cancel()}
else { print(seconds) }
}
timer.resume()
var lock = NSLock()
var array = Array(1...10000)
func getLastItem() -> Int {
// lock.lock()
// var temp:Int? = nil
// if array.count > 0 {
// temp = array[array.count - 1]
// }
// lock.unlock()
// return temp
return arrayQueue.sync { () -> Int in
if array.count > 0 {
return array[array.count - 1]
}
return -1
}
}
func removeLastItem() {
// lock.lock();
// array.removeLast()
// lock.unlock()
let workItem = DispatchWorkItem(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
array.removeLast()
}
arrayQueue.async(execute: workItem)
}
queue.async {
for _ in 0..<10000 {removeLastItem()}
}
queue2.async {
for _ in 0..<10000 {print(getLastItem()) }
// if let item = getLastItem() { print( getLastItem() )}
}
// 多线程其他模式:
// promise
// pipeline
// master-slave
// serial Thread confinement
//4. error
//------------------------------------------------------------------------------------------------
enum VendingMachineError:Error {
case invalidSelection
case insufficientFunds(coinsNeeded:Int)
case outOfStock
}
// 商品
struct Item {
var price:Int
var count:Int
}
// 自动售货机
class VendingMachine {
var inventory = [
"ctr":Item(price: 6, count: 8),
"Chips":Item(price: 10, count: 9),
"Breed":Item(price: 15, count: 5)
]
// 投币
var coinsDesPosited = 0
// 售卖
func vend(itemName:String) throws {
defer {
print("exit to clean")
}
guard let item = inventory[itemName] else {
throw VendingMachineError.invalidSelection
}
guard item.count > 0 else {
throw VendingMachineError.outOfStock
}
guard coinsDesPosited >= item.price else {
throw VendingMachineError.insufficientFunds(coinsNeeded: item.price-coinsDesPosited)
}
var newItem = item
newItem.count -= 1
inventory[itemName] = newItem
print("sell to success...")
}
}
var machine = VendingMachine()
machine.coinsDesPosited = 5
do {
try machine.vend(itemName: "Chips")
}catch VendingMachineError.invalidSelection {
print("no such thing")
}catch VendingMachineError.insufficientFunds(let coninsNeeded){
print("u need more coins \(coninsNeeded)")
}catch VendingMachineError.outOfStock {
print("out Of Stock")
}catch {
print("unexpected error")
}
//------------------------------------------------------------------------------------------------
//5 不透明类型
protocol Shape {
func draw() -> String
}
struct Triangle:Shape {// 三角(形)
func draw() -> String {
var res = [String]()
for len in 1...size {
res.append(String(repeating: "*", count: len))
}
return res.joined(separator: "\n")
}
var size:Int
}
//print(Triangle(size: 5).draw())
struct Square:Shape {
var size:Int
func draw() -> String {
var res = [String]()
for _ in 0..<size {
res.append(String(repeating: "*", count: size))
}
return res.joined(separator: "\n")
}
}
//FlippedShape confirm to Shape协议, 泛型 T 有一个约束Shape
struct FlippedShape<T:Shape>:Shape {
func draw() -> String {
let res = shape.draw().split(separator: "\n")
return res.reversed().joined(separator: "\n")
}
var shape:T
}
struct JoinedShape<T:Shape,U:Shape>:Shape {
var top:T
var bottom:U
func draw() -> String {
return top.draw() + "\n" + bottom.draw()
}
}
// top:Triangle
// mid:square
// bottom: Triangle 反转
//func makeTapezoid() -> JoinedShape<Triangle,JoinedShape<Square,FlippedShape<Triangle>>> { or some Shape 不透明类型
func makeTapezoid(size:Int) -> Shape {// some Shape 不透明类型 只能返回一种特定的类型,不能跟据不同分支 条件判断 返回不同几种类型
// 用some Shape不透明类型 ,去掉if语句
if(size == 3) {
return Square(size:3)
}
let t = Triangle(size: size)
let s = Square(size: size)
let f = FlippedShape(shape: t)
return JoinedShape(top: t, bottom: JoinedShape(top: s, bottom:f))
}
//print(makeTapezoid(size:3).draw())
protocol Container_v1 {
associatedtype Item
var count:Int{get}
subscript(index:Int) -> Item {get}
}
//Array 遵循Container_v1 协议
extension Array:Container_v1{}
func makeProtocolContainer<T>(item:T) -> some Container_v1 { //一定要用不透明类形
return [item]
}
//无主引用: unowned :has default value,and canot assign to nil
//6 inout参数访问冲突
// 同时读和写了
//Simultaneous accesses to 0x10c926ff0, but modification requires exclusive access.
//Previous access (a modification) started at (0x10c927374).
//Current access (a read) started at:
var stepSize = 1
func increment(_ num: inout Int) {
num += stepSize
}
// increment(&stepSize) // 冲突
var copyOfStepSize = stepSize
increment(©OfStepSize)
stepSize = copyOfStepSize
struct Player {
var name:String
var health:Int
var eneygy:Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
}
extension Player {
mutating func shareHealth(with teammate:inout Player) {
balance(hea1: &teammate.health,hea2: &health)
}
func balance(hea1:inout Int,hea2:inout Int) {}
}
var oscar = Player(name: "Oscar", health: 10, eneygy: 10)
var maria = Player(name: "Maria", health: 5, eneygy: 10)
oscar.shareHealth(with: &maria)
//oscar.shareHealth(with: &oscar) // 冲突
// 7. third lib
//pod 'Alamofire','~> 5.5.5-rc.2'
//pod 'SwiftyJSON','~> 4.0'
//r.swift可以获取强类型、自动完成的资源,如图像、字体和段落完全类型化。
//更少的强制转换和猜测方法将返回什么编译时检查,运行时不再有导致应用程序
//崩溃的错误字符串自动完成,再也不用怀疑图片名字是不是复制错
//pod 'R.swift'
//pod 'MonkeyKing'//
//MonkeyKing helps you post SNS messages to Chinese Social Networks, without their buggy SDKs
//pod 'Kingfisher'
//pod 'SnapKit','~> 5.0.0'
//Dollar 是一个第三方扩展。
//包括了。Array,Dictionary,Object,Function,Chaining
//导入Dollar 直接使用即可
//pod 'Dollar'
//8 swift 消息派发方式
//直接派发
//函数表派发 Vitual table
//消息机制派发:不管是纯Swift类还是继承NSObject 的类只要在属性和方法前面添加@objc 关键字可以使用runtime
//swift runtime
// 原始定义 扩展
//值类型 直接派发 直接派发
//协议 函数表派发 直接派发
//类 函数表派发 直接派发
//继承自NSOBject的类 函数表派发 消息机制派发
//修饰符
//final 直接派发
//dynamic 消息机制派发
//@objc & @nonobjc 改变在OC里的可见性
//@inline 告许编译器可以直接派发
//9.混编:
//NS_SWIFT_NAME: 在OC中,重新命名在swift中的名称
//NS_SWIFT_UNAVAILABLE ,在Swift中不可见,不能使用
// 混编:
//1.对于自定义的类而言,OC的类,不能继承Swift的类,即要混编的OC类不能是Swift类的子类
//反过来,需要混编的Swift类可以继承自OC的类
//2. swift没有宏定议的
//#define TOOLLABAR_HEIGHT 44
//let TOOLLABAR_HEIGHT = 44
// 常量不变化值
//#define SCREEN_WIDTH ([[UISCREEN mainScreen]bounds].size.width)
//let SCREEN_WIDTH = UISCreen.mainScreen().bounds.size.width
// 常量变化值
//#define STATUS_BAR_HEIGHT ([UIApplication sharedApplication].statusBarFrame.size.height);
//func STATUS_BAR_HEIGHT() -> CGFloat {
// return UIApplication.sharedApplication().statusBarFrame.size.height
//}
//带参的宏
//#define RGB_COLOR(r,g,b) [UIColor colorWithRed:r/255.f green:g/255.f blue:b/255 alpha:1.0]
//func RGB_COLOR(r:CGFloat,g:CGFloat,b:CGFloat) -> UIColor {
// return UIColor(red:r,green:g,blue:b,alpha:1.0)
//}
//3.swift的独有特性,如果要提供给OC中调用,不要使用OC中没有的特性
//swift中有许多OC没有的特性,比如,元组为一等公民函数,还有特有的枚举类型,所以要使用的混编文件要注意Swift独有属性问题
// 4.OC API和SWIFT的风格相差比较大,SWIFT调用OC的API 时可能由于数据类型等不一致无法达到预期
//(OC方法采用C语言风格的多参类型,OR OC
//方法返回NSNotFound,在Swift中期望返回nil),这时候就要 NS_REFINED_FOR_SWIFT了
//@interface MyClass:NSObject
//-(NSUInteger)indexOfString:(NSString*)aString NS_REFINED_FOR_SWIFT:
//@end
//extension MyClass {
// func indexOfString(aString:String!) -> Int? {
// let index = Int(__index(of:aString))
// if(index == NSNotFound) {
// return nil
// }
// return index
// }
//}
//10.
//Carthage 主张去中心化和非侵入性
//CocoaPods搭建了一个中心库,第三方库被收入到该中心库,所以没有收录的第三方库是不能使用CococoaPod管理的,这就是所谓的中心化思想
//Carthage 没有这样的中心库,第三主库基本上都是从GitHub或者私有Git库中下载的,这就是去中心化
//另外CocoaPods下载第三方库后,会将其编译成静态链接库或者动态框架文件,这种做法会修改Xcode 项目属性配置依赖关系。这就是所谓的侵入性,而Carthage 下载成功后,会将第三库编译成动态框架,由开发人员自己配置依赖关系,Carthage不会修改XCODE项目属性,这就是所谓的非侵入性
//setup carthage
//brew 安装 carthage
//1> brew update
//2> brew install carthage
//3> 工程下创建:touch Cartfile
//github "Alamofire/Alamofire" ~> 5.2
//github "onevcat/Kingfisher" ~> 6.0
//github "nixzhu/MonkeyKing"
//github "SwiftyJSON/Alamofire-SwiftyJSON" "master"
//github "SnapKit/SnapKit" ~> 5.0.0
//4>carthage update --platform iOS
//5>config:
//Framework Search Paths:
//$(PROJECT_DIR)/Carthage/Build/iOS
//Build Phases ->run Script
//shell ->/bin/sh:
//usr/local/bin/carthage copy-frameworks
// input files:
//$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
//xcode->file->swift packages:
//https://github.com/Alamofire/Alamofire.git
网友评论