不管生活如何端姚,還是要不停學(xué)習(xí)。
一年前的我一直在寫OC挤悉,對(duì)底層了解不是很深刻渐裸,17年開始一直寫swift,一開始在項(xiàng)目中遇到了各種困難装悲,沒有辦法昏鹃,只能克服。這篇文章的核心是呈現(xiàn)在在真實(shí)的工作中遇到的點(diǎn)诀诊,雖然有些簡(jiǎn)單的令人發(fā)指洞渤,不過走一遍應(yīng)該會(huì)有些感悟。加油属瓣。
1.三目運(yùn)算符
三木運(yùn)算符號(hào) 中的 载迄?前面一定有一個(gè)空格。這是 抡蛙? 因?yàn)橐獏^(qū)分 是 三目 還是 optional~ 如下:
let f = true
f? 2 : 3 //錯(cuò)誤
f ? 2 : 3 //正確
2.報(bào)錯(cuò):this class is not key value coding-compliant for the key... 這個(gè)報(bào)錯(cuò) 可能是因?yàn)?xib 里面的鏈接有錯(cuò)誤 或者是 自定義的類中沒有實(shí)現(xiàn)對(duì)應(yīng)的屬性值护昧。
3.懶加載
懶加載在swift中很常用,一定要注意格式粗截,要不然提示的錯(cuò)誤可能有點(diǎn)找不到北惋耙。。
private var unityview:UnityAppController = {
let ua = UnityAppController()
ua.startUnity(UIApplication.sharedApplication())
return ua
}() // 注意后面一定有一個(gè) 括號(hào)
4.====
extension 在swift中經(jīng)常用來分離代碼慈格,不過需要注意的是在swift 的extenion中是 不能 定義一個(gè)存儲(chǔ)型變量的怠晴,存儲(chǔ)型變量和計(jì)算性變量如果不熟悉可以去先研究一下這里,和OC中的屬性是不同的概念浴捆。
5.控件初始化
使用懶加載的方式加載出來的控件 例如上面 3.懶加載里面的截圖所示蒜田,得到的控件初始化的過程是只會(huì)執(zhí)行一次。
6.用didSet 設(shè)置一個(gè)button的控制狀態(tài)
如按鈕點(diǎn)擊后對(duì)應(yīng)的狀態(tài)有所改變
var seletedBtnView :DiscountBtnView? {
didSet{
oldValue?.btn?.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
oldValue?.label?.textColor = UIColor.blackColor()
oldValue?.btn?.layer.borderColor = UIColor.init(bd_hexColor: "F99C35").CGColor
oldValue?.btn?.backgroundColor = UIColor.whiteColor()
seletedBtnView?.btn?.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
seletedBtnView?.label?.textColor = UIColor.init(bd_hexColor: "F99C35")
seletedBtnView?.btn?.layer.borderColor = UIColor.init(bd_hexColor:"F99C35").CGColor
seletedBtnView?.btn?.backgroundColor = UIColor.init(bd_hexColor:"F99C35")
}
}
7.swift數(shù)組獲取index
swift在這里確實(shí)比OC有那么一點(diǎn)麻煩选泻,我的方法不一定是最好的冲粤。。
swift 3
let person1 = Person(name: "John")
let person2 = Person(name: "Sue")
let person3 = Person(name: "Maria")
let person4 = Person(name: "Loner")
let people = [person1, person2, person3]
let indexOfPerson1 = people.index{$0 === person1} // 0
let indexOfPerson2 = people.index{$0 === person2} // 1
let indexOfPerson3 = people.index{$0 === person3} // 2
let indexOfPerson4 = people.index{$0 === person4} // nil
8.swift 里面 除法可能需要這么個(gè)形式
CGFloat(index!).truncatingRemainder(dividingBy: 3)
9.automaticallyAdjustsScrollViewInsets
默認(rèn)是 true 這個(gè)在OC里面很多時(shí)候就有些作祟页眯,所以還是寫出來沒準(zhǔn)布局有問題就是因?yàn)檫@貨梯捕。
10.swift中的init方法的初始化問題
這個(gè)如果是自己定義的init方法需要注意完整的初始化。如果有需要我這里有文檔而已提供窝撵。
11.初始化閉包的時(shí)候要看好了對(duì)應(yīng)的括號(hào)傀顾。。
var mapMoveClosure:(() -> ())? // 這么寫 注意 有一個(gè)括號(hào)
12.調(diào)用marsony動(dòng)畫 需要使用的是:
[UIView animateWithDuration:0.25 animations:^{
[self.pickerView layoutIfNeeded];
}];
13.有xib的視圖(controller) 如果在viewdidload中使用了 width = self.view 會(huì)被布局成 width = 600 碌奉。 用了 xib 再使用 marsony布局需要注意了短曾。 這個(gè)需要敲黑板了:!找了半天~(這個(gè)是在swift2.3項(xiàng)目中嫉拐,3.0沒測(cè)試)
14.我們使用的handyJson解析json數(shù)據(jù)哩都。在使用中如果遇到了系統(tǒng)的關(guān)鍵字可以使用如下方式替換:
handyJSON 使用 遇到系統(tǒng)的字段 可以使用
mutating func mapping(mapper: HelpingMapper) {
mapper.specify(property: &ddfault, name: "defalut")
}
我沒使用過swiftyJson??.
15.獲取當(dāng)前顯示的(最上層的)ViewController
static func getVisibleViewController() -> UIViewController? {
guard let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController where rootVC.childViewControllers.count>0, let navigationVC = rootVC.childViewControllers[0] as?UINavigationController else {
return nil
}
let currentVC = navigationVC.visibleViewController
guard let index = currentVC?.tabBarController?.selectedIndex where rootVC.childViewControllers.count>index+1,let currentNav = rootVC.childViewControllers[index] as?UINavigationController else {
return nil
}
return currentNav.visibleViewController
}
16.遞歸
寫遞歸的時(shí)候 一定要注意結(jié)束的標(biāo)志 只要有一個(gè)return 就直接全部都返回了
注意里面的 if let sub = findsubView 這個(gè)條件是 找到了才進(jìn)行 return 原來的可能直接就返回了 nil。
另外遞歸最好是用 尾遞歸的方式婉徘,喵神的《swift 100 Tips》里面的最后章節(jié)有講漠嵌,沒有這個(gè)書可以找我要。??
17.DispatchQueue.global
DispatchQueue.global(qos: .default).async { //swift 3 現(xiàn)在換成這種方式進(jìn)行調(diào)用global
}
18.創(chuàng)建一個(gè) 隊(duì)列 添加一個(gè) item 具有 cancel功能
這個(gè)以前是Operation專屬盖呼,現(xiàn)在GCD也可以這么干啦儒鹿。~
let queue = DispatchQueue(label: "zhangTest1")
let workItem = DispatchWorkItem(qos: .default, flags: .assignCurrentContext) {
print("workItem")
}
queue.asyncAfter(deadline: DispatchTime.now() + time, execute: workItem)
workItem.cancel()
print(workItem.isCancelled)
19.delay方法&取消的方式
import UIKit
typealias task = (_ cancel : Bool) -> Void //返回一個(gè)這樣的block
class Tools {
static func delay(time : TimeInterval, block : @escaping () -> ()) -> task? {
func delay_func(dblock : @escaping () -> ()) { //真正執(zhí)行的func
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time, execute: dblock)
}
var result: task?
var closure : (() -> Void)? = block // 重復(fù)調(diào)用task(false)會(huì)有問題。
let delayedClosure : task = { cancel in // 使用帶有 cancel 的方法進(jìn)行包裹几晤。
if let c = closure {
if cancel == false {
c()
}
}
closure = nil
result = nil // 如果提前結(jié)束 這里面也是nil了 如果不是提前結(jié)束 那么清理任務(wù) 方便下一次執(zhí)行挺身。
}
result = delayedClosure // 可選形 這個(gè)是因?yàn)樘崆叭∠丝赡軙?huì)產(chǎn)生nil 也正好不用執(zhí)行了。锌仅。
delay_func {
if let delayedClosure = result {
delayedClosure(false)
}
}
return delayedClosure
}
static func cancel(t : task) { // 外部不要直接調(diào)用 t(true) 或者 t(flase) 這樣很危險(xiǎn)章钾。
t(true)
}
}
let delayTask = Tools.delay(time: 2) {
print("exe")
}
Tools.cancel(t: delayTask!) //可以取消的~
20.想用 Swift 來實(shí)現(xiàn) KVO
需要做額外的工作,那就是將想要觀測(cè)的對(duì)象標(biāo)記為 dynamic热芹。
class MyClass: NSObject {
dynamic var date = Date()
}
//如果是 不能回去源代碼的可以使用重寫的方式贱傀。
class MyClass: NSObject {
var date = Date()
}
class MyChildClass: MyClass {
dynamic override var date: Date {
get { return super.date }
set { super.date = newValue }
}
}
(三方: Observable-Swift 如果需要可以試試)
21.字符串轉(zhuǎn)換到 UnsafeMutablePointer<Int8>
let name = "classvarB"
let greeting : UnsafeMutablePointer<Int8> = strdup(name)
print(class_getInstanceVariable(classTestB.self, greeting))
22.var 和可選型是 沒有關(guān)系的。 這個(gè)一定要注意伊脓。
23.書寫控件的時(shí)候盡量使用懶加載的形式 注意 懶加載的時(shí)候 控件屬于強(qiáng)引用 removeFromsuperView 不會(huì)釋放府寒。頁(yè)面消失的時(shí)候進(jìn)行釋放。
24.當(dāng)viewcontroller里面引用了 一個(gè)網(wǎng)絡(luò)請(qǐng)求报腔。 網(wǎng)絡(luò)請(qǐng)求里面有一個(gè)回調(diào)(CSChooseGoodNetWork)株搔,回調(diào) 閉包 而且這里面添加上了 @escaping 調(diào)用的類 CSChooseGoodView 里面進(jìn)行調(diào)用的時(shí)候 里面所有的 fileprivate 和 private 都需要去掉才能使用。
25.直接創(chuàng)建一個(gè) 枚舉值 GoodsPromotionType.init(rawValue: type)
enum GoodsPromotionType:String {
case limiteDiscount = "1" //限時(shí)折扣
case discount = "2" //滿件折扣
case fullDisReduction = "3" //滿減
case fullReduction = "4" //一口價(jià)
}
26.添加上 dynamic 可以使用 OC 的method swizzle方法進(jìn)行方法交換
參考
27.class func (類方法中)中不能 使用非 class 修飾的func(實(shí)例方法)
28.模擬器和真機(jī)
模擬器和真機(jī)的 區(qū)別
#if arch(i386) || arch(x86_64) //模擬器
#else //真機(jī)
var traceInstance: BTRACE? //比方說 初始化一個(gè)電子圍欄服務(wù)
#endif
29.自動(dòng)框架庫(kù)Snapkit 里面 使用 snp update 不管用纯蛾?纤房? remake 才可以~ 這個(gè)還沒找原因。
30.private func 這個(gè)方法 不能用在 tap手勢(shì)上(多么痛的領(lǐng)悟翻诉。炮姨。), 不能多個(gè)控件添加 一個(gè)手勢(shì)。
31.錯(cuò)誤 Argument of '#selector' does not refer to an initializer or method 原因是 selector 里面的 不能寫成 method() 有括號(hào)就錯(cuò)了(有括號(hào)不就是調(diào)用了么~)
32.截屏的代碼
UIGraphicsBeginImageContext(size)
let text = UIGraphicsGetCurrentContext()!
self.view.layer.render(in: text)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
33.頁(yè)面邏輯(側(cè)滑)代碼
func panSliderView(panGes:UIPanGestureRecognizer) {
let translation = panGes.translationInView(self.view)
let centerX = panGes.view!.center.x + translation.x
let another :CGFloat = sliderLeftMargin + (ScreenWidth - sliderLeftMargin) / 2.0
//限制不能超過邊線碰煌。
if centerX >= another {
panGes.view?.center = CGPointMake(centerX, panGes.view!.center.y)
}
panGes.setTranslation(CGPointZero, inView: self.view)
if (panGes.state == .Ended && (centerX != another) && (centerX != sliderLeftMargin + sliderWidth)) { //判斷一下中心店的距離 再做相應(yīng)的動(dòng)畫舒岸。
if centerX < sliderLeftMargin + sliderWidth {
//向左移動(dòng)
viewAnimation(slideView,frame: leftFrame)
} else {
//向右移動(dòng)
hiddenSlider()
}
}
}
34.pod
pod install --verbose --no-repo-update 這個(gè)pod命令可以添加那些非本地的
pod update --verbose --no-repo-update
pod 'EaseUI', :path => '../EaseUI' // pod 安裝本地庫(kù).
pod update 報(bào)錯(cuò)
zsh: /usr/local/bin/pod: bad interpreter: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin: no such file or directory
解決:
sudo gem uninstall cocoapods
sudo gem install -n /usr/local/bin cocoapods
pod 只更新新的 原來的就不更新了。
pod update --verbose --no-repo-update
sudo gem install -n /usr/local/bin cocoapods --pre
35.xib中 commend + option + 加號(hào) 快速 update frame芦圾。
36.尋找第一響應(yīng)者
extension UIView {
func getCurrentFirstResponder() -> UIView? {
for subView: UIView in self.subviews as [UIView] {
if subView.isFirstResponder() {
return subView
}
else {
if let sub = subView.getCurrentFirstResponder() {
return sub;
}
}
}
return nil
}
}
37.swift3.0 改變了許多的語法 例如 NSDate 變成了 變成了建議使用 Date蛾派,那么擴(kuò)展里面是不能通用的 會(huì)找不到方法,2.3版本升級(jí)的時(shí)候需要注意。
38.xib 上面添加了 一個(gè)手勢(shì) 要注意 加載的時(shí)候?qū)懙氖?first 還是 last 洪乍,另外沒有 file owner 綁定的時(shí)候 加載的fileowner 可以寫成nil
39.原來關(guān)鍵字可以這么使用啊
var `default` = 2
func test() {
print(`default`)
self.default = 4
}
40.枚舉可以這么寫
enum Section: Int {
case input = 0, todos, max
}
42.switch可以這樣寫
switch sender.tag {
case 1,2:
order = sender.tag
.....
}
43.數(shù)組的 contains 方法是比較的 哈希值 所以 “1” 這樣的對(duì)象可以直接 比較梭依,不必在乎是不是同一個(gè)對(duì)象。
44.reduce 方法
let arr = [1,2,3,4]
arr.reduce("") { (result, intt) -> String in
return result + "\(intt)"
}
// 初始值 中間結(jié)果 中間的添加因子 返回的結(jié)果
arr.reduce([]) { (result, inttt) -> [String] in
return result + ["\(inttt)"]
}
arr.reduce([]) { (result, inttt) -> [Int] in
print(result)
print(inttt)
return result + [inttt]
}
45.OC里面 很多options里面的參數(shù)是枚舉使用 | 連起來典尾,表示同時(shí)滿足,swift里面是這樣的:
self.thumbBtn.setTitle(mappedObject.datas?.praise_num, forState: [UIControlState.Normal,UIControlState.Selected]) //數(shù)組表示糊探。
46.使用網(wǎng)頁(yè)打開應(yīng)用
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>CSC</string>
<key>CFBundleURLSchemes</key>
<array>
<string>CSCMall</string>
</array>
</dict>
</array>
調(diào)起方法 CSCMall://CSC
47.插入視圖的方法:
self.view.insertSubview(scrollView, atIndex: 0); 可以是這樣用的用來控制層級(jí)钾埂,這個(gè)方法盡量別在tableView的cell上或者能滑動(dòng)View上使用,因?yàn)榭ǎ?/p>
48.collectionview 轉(zhuǎn)換卡片和 列表科平。
private func setHorizionLayout() {
let layout = UICollectionViewFlowLayout()
// 設(shè)置最小行間距 10
layout.minimumLineSpacing = 10;
// 設(shè)置每個(gè)cell之間間距
layout.minimumInteritemSpacing = 0;
// 設(shè)置每一組的間距褥紫,距離頂部的距離
layout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5)
layout.itemSize = CGSizeMake((ScreenWidth - 20.0)/2, (ScreenWidth - 20.0)/2+68)
collectionView.collectionViewLayout = layout
}
//設(shè)置一行一個(gè)的。類似tableView的情況
private func setVerticalLayout(){
let layout = UICollectionViewFlowLayout()
// 設(shè)置最小行間距 10
layout.minimumLineSpacing = 10;
// 設(shè)置每個(gè)cell之間間距
layout.minimumInteritemSpacing = 0;
// 設(shè)置每一組的間距瞪慧,距離頂部的距離
layout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5)
layout.itemSize = CGSizeMake(ScreenWidth-10.0, 125)
collectionView.collectionViewLayout = layout
}
可以設(shè)置 collectionView.collectionViewLayout = layout 用于視圖轉(zhuǎn)換髓考, 這里面的東西可以用來 轉(zhuǎn)換列表和卡片視圖。
49.使用 try catch
var s : Reachability?
do {
try s = Reachability.init(hostname: "http://www.baidu.com")
} catch {
switch (error)
print("Reachability 創(chuàng)建 init 出錯(cuò)弃酌。")
print(error) //獲取的error
}
50.** 設(shè)置 nav上面的 right left buttonItem**
portraitUserVc.navigationItem.rightBarButtonItem?.setTitleTextAttributes([NSFontAttributeName:UIFont.systemFontOfSize(16),NSForegroundColorAttributeName: UIColor.orangeColor()], forState: .Normal)
51.使用for-in 進(jìn)行循環(huán)遍歷. ---> 另外純遍歷可以使用foreach
for (index,element) in orderGoodsList.enumerate() { //這個(gè)方法不錯(cuò)氨菇, 可以舍棄 for i in 0..<5 的形式了。
detailView.idItem = element
}
52.注意 橋接文件里面的數(shù)據(jù)妓湘,相當(dāng)于每個(gè)文件包含了一次查蓉。可能會(huì)造成沖突榜贴。(三方庫(kù)里面有不少一樣的名字豌研,那么廢了~)
53.復(fù)制到粘貼板
let pasteboard = UIPasteboard.generalPasteboard()
pasteboard.string = orderCodeLabel.text
SVProgressHUD.showSuccessWithStatus("已復(fù)制到粘貼板") // 復(fù)制到粘貼板~
54.automaticallyAdjustsScrollViewInsets = false 這貨在OC里面就作祟很久了。
55.創(chuàng)建控件的時(shí)候 同時(shí)創(chuàng)建了一個(gè)閉包唬党。 這時(shí)候需要注意里面的 self鹃共。另外, 這里的 snp_makeConstraints 是調(diào)用方法,tapBackClosure是一個(gè)存儲(chǔ)屬性驶拱。
lazy var messageReason : ZMReFundMessageReasonView = {
let v = NSBundle.mainBundle().loadNibNamed("ZMReFundMessageReasonView", owner: self, options: nil)?.first as! ZMReFundMessageReasonView
self.view.addSubview(v)
v.snp_makeConstraints { (make) in
make.top.equalTo(self.goodsStatus.snp_bottom).offset(1)
make.left.right.equalTo(self.view)
make.height.equalTo(self.view).multipliedBy(0.08)
}
v.tapBackClosure = {[unowned self] in //點(diǎn)擊了出現(xiàn)原因的霜浴。
self.alertActionSheet.showInView(self.view)
}
return v
}()
// 這個(gè)我也有點(diǎn)忘記是咋回事了,回頭再看看~
56.enum 攜帶變量的形式
enum Number1 {
case one(count:Int,string:String)
case two(count:Int)
}
var num1 = Number1.one(count: 5,string: "zhang") //枚舉攜帶變量的形式
var num2 = Number1.two(count: 3)
switch num2 {
case .one(let count,let name): //這個(gè)地方主要要有一個(gè)let
print(count)
print(name)
case let .two(count): //只有一個(gè)常量可以卸載 let 可以寫到前面蓝纲。
print(count)
default:
print("defalut")
}
57.中文轉(zhuǎn)換成拼音坷随, 用于檢索。(例如中文按照拼音排序)
let personArray = [Person(name: "zhang"),Person(name: "han")]
let sortArray = personArray.sorted { (p1, p2) -> Bool in //直接排序有問題驻龟。
p1.name > p2.name
}
func transForm(chinese:String) -> String {
let mutableStr = NSMutableString(string: chinese) as CFMutableString
var cfRange = CFRange.init(location: 0, length: 0)
// kCFStringTransformStripCombiningMarks 去掉重音符號(hào)
let _ = CFStringTransform(mutableStr, nil, kCFStringTransformToLatin, false)
let _ = CFStringTransform(mutableStr,nil, kCFStringTransformStripCombiningMarks, false) // false 是反轉(zhuǎn)的意思
// 這個(gè)地方為什么能傳nil 温眉?? 又是為什么這里 (location: 0, length: 0) 還能使用啊翁狐。~类溢?
let _ = CFStringTransform(mutableStr, &cfRange, kCFStringTransformStripCombiningMarks, false)
// print(mutableStr)
return mutableStr as String
}
transForm(chinese: "張")
// 這樣增加了 trans的使用次數(shù)
let sorta2 = personArray.sorted { (p1, p2) -> Bool in
return transForm(chinese: p1.name) > transForm(chinese: p2.name)
}
// 排序的具體流程可以這樣 中途保存了 原始的中文名稱
let sort3 = personArray.map { (p) -> (String, String) in
return (p.name, transForm(chinese: p.name))
}.sorted { (t1, t2) -> Bool in
return t1.1 < t2.1
}.map { (t) -> String in
t.1
}
// 簡(jiǎn)化版本
let sort4 = personArray.map { //轉(zhuǎn)換中文
transForm(chinese: $0.name)
}.sorted()
58.@warn_unused_result 寫sdk的時(shí)候 可以去掉返回值沒有調(diào)用的警告
59.lipo命令合并和拆分IOS靜態(tài)庫(kù)
具體參考
60.判斷是不是中文的。
- (BOOL)isChinese
{
NSString *match = @"(^[\u4e00-\u9fa5]+$)";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];
return [predicate evaluateWithObject:self];
}
61.限制一個(gè) swift 類是controller 又滿足了一個(gè)協(xié)議。
class func requestNewData<T:NewGoodsSellNetWorkProtocol where T:UIViewController>(controller:T) {
}
如果多個(gè)方法都需要使用這個(gè)泛型 闯冷, 那么就定義在類上
class RequestNewGoodsSell<T:NewGoodsSellNetWorkProtocol where T:UIViewController> {
62.@objc protocol NewGoodsSellNetWorkProtocol 添加protocol 中的方法為#selector的時(shí)候需要在前面添加上@objc
63.在iOS 8以后的版本中 GCD 變化比較大砂心,time 直接可以用 TimeInterval 類似可以這樣:
let time: TimeInterval = 2.0
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time) {
print("2 秒后輸出")
}
DispatchWorkItem創(chuàng)建出來的item是可以實(shí)現(xiàn)取消的。
let item = DispatchWorkItem {
print("1235")
}
let myQueue = DispatchQueue(label: "我的線程")
myQueue.async(execute: item) //這個(gè)便執(zhí)行了 對(duì)應(yīng)的block
item.cancel() // 這里可以實(shí)現(xiàn)取消蛇耀。
DispatchQueue.main.async(execute: item)
//另外辩诞,在playground中 貌似 DispatchQueue.main.asyncAfter 這個(gè)方法是不管用的。playground貌似不支持 DispatchQueue.main
··
64.獲取類名
//swift 2.3
static var Identify:String{
return (String.init(UTF8String: object_getClassName(self)) ?? "").componentsSeparatedByString(".").last!
}
//swift 3.0
var className: String {
return String.init(cString: class_getName(object_getClass(self))) //獲取類的名字
}
65.Mirror 可以實(shí)現(xiàn)Struct 的子類遍歷(children). 這個(gè)可以看看 HandyJson的相關(guān)代碼纺涤。
66.關(guān)聯(lián)類型 E 可以是滿足一個(gè)協(xié)議的泛型译暂,這個(gè)協(xié)議在實(shí)現(xiàn)中也是必須要聲明成正確的類型。
protocol Rle:Ele {
}
protocol CommandProtocol {
associatedtype E : Ele
func on()
}
class P : Ele {
}
class CommandCondtion:CommandProtocol {
typealias E = P
func on() {
print("1")
}
}
額.....說好的 100 個(gè)呢撩炊?外永? 好吧。其他的有的是讓我合并了拧咳,有的是我的低級(jí)失誤伯顶,我真的寫了100個(gè)!放一個(gè)圖片為證:
這里還會(huì)不停的更新骆膝!
有問題請(qǐng)QQ:645360439祭衩。
不開心的時(shí)候就努力學(xué)習(xí),加油阅签!
最后更新是 2018.01.19汪厨。