Swift 4 Cheat Sheet Advanced
Swift 4 Cheat Sheet Advanced
@(程式設計筆記)[Swift]
Singleton
class MyManager {
static let shared = MyManager()
private init() {
}
}
GCD
DispatchQueue.global().async {
// Some async works
DispatchQueue.main.async {
// Update UI
}
}
Selector
let timer = Timer(timeInterval: 1, target: object,
selector: #selector(MyClass.test),
userInfo: nil, repeats: false)
button.addTarget(object, action: #selector(MyClass.buttonTapped),
for: .touchUpInside)
view.perform(#selector(UIView.insertSubview(_:aboveSubview:)),
with: button, with: otherButton)
Cases where #selector
doesn't work, and naming: Sometimes you don't have a function reference to make a selector with (for example, with methods dynamically registered in the ObjC runtime). In that case, you can construct a Selector
from a string: e.g. Selector("dynamicMethod:")
— though you lose the compiler's validity checking. When you do that, you need to follow ObjC naming rules, including colons (:
) for each parameter.
Control Flow
Switch
let someCharacter: Character = "z"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(someCharacter) is a vowel")
case "z":
print("The last letter of the alphabet")
default:
print("Some other character")
}
// Prints "The last letter of the alphabet"
https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html
Functions
Overloading
func output(x:Int) {
print("The int value is \(x)")
}
func output(x:String) {
print("The string value is \(x)")
}
Default value
@objc public class func checkNewAppVersionAvailable(
userID: String = "",
higherThan minBuildNo: Int = -1) -> Bool
let result = checker.checkNewAppVersionAvailable()
注意:
如果設定為nil,那麼會使用OC預設初始化值,以Bool為例就是false,並不會使用default value,也就是說,OC無法享受預設帶參的便利。
https://docs.swift.org/swift-book/LanguageGuide/Functions.html
Closures(block)
https://docs.swift.org/swift-book/LanguageGuide/Closures.html
// 宣告一個閉包(有兩個整形引數,且返回值為整形的閉包)
var sumClosure:((a: Int, b: Int) -> Int)
// 帶block方法宣告
public func checkNewAppVersionAvailable(
success successCallback: @escaping ((_ hasNewVersion: Bool, _ info: [String: Any]?) -> Void),
failure failureCallback: @escaping ((Error) -> Void))
// 方法呼叫
checker.checkNewAppVersionAvailable(success: { (_, _) in
}) { (_) in
}
Weak self
lazy var printName: ()->() = {
[weak self] in
if let strongSelf = self {
print("The name is \(strongSelf.name)")
}
}
Enumerations
enum Pet{
case dog
case cat
case rabbit
}
var hisPet = Pet.dog
var herPet: Pet = .dat
RawValue
enum Pet: String {
case dog = "?"
case cat = "?"
case rabbit = "?"
}
var myPet = Pet.rabbit
print("my pet is a \(myPet.rawValue)") //output: my pet is a ?
var timsPet = Pet(rawValue: "?")
print("Tim's pet is a \(timsPet.rawValue)")//output: Tim's pet is a ?
Properties
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
Read only
public private(set) var hours: Int = 0
Lazy Stored Properties
lazy var zyTableView: UITableView = {
let tempTableView = UITableView (frame: self.view.bounds, style: UITableViewStyle.Plain)
tempTableView.delegate = self
tempTableView.dataSource = self
return tempTableView
}()
Computed Properties(Setter and Getter)
Computed properties do not actually store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.
Setters and Getters apply to computed properties; such properties do not have storage in the instance - the value from the getter is meant to be computed from other instance properties. In your case, there is no x to be assigned.(劃重點:private var _x: Int = 0,計算屬性不會自動生成_成員變數,只是提供 set 和 get 兩種方法)
Explicitly: "How can I do this without explicit backing ivars". You can't - you'll need something to backup the computed property.
https://stackoverflow.com/questions/24025340/property-getters-and-setters
class Point {
private var _x: Int = 0 // _x -> backingX, won't be created automatically like those in Objective-C
var x: Int {
set { _x = 2 * newValue } // newValue is the default name of new value
get { return _x / 2 }
}
}
Property Observers(willSet 和 didSet)
willSet didSet屬性觀測用來更新關聯屬性
struct Circle {
var radius: Double = 0 {
didSet {
perimeter = 2 * Double.pi * radius
}
}
private(set) var perimeter: Double = 0
}
var circle = Circle()
circle.radius = 2
print(circle.perimeter) //output: 12.5663706143592
想在一個屬性定義中同時出現 set 和 willSet 或 didSet 是一件辦不到的事情。計算屬性中我們可以通過改寫 set 中的內容來達到和 willSet 及 didSet 同樣的屬性觀察的目的。
Optional Chaining
https://docs.swift.org/swift-book/LanguageGuide/OptionalChaining.html
OC介面橋接
OC 的介面橋接到 Swift 後預設都是nonnull
,這點和OC不一樣,OC的所有指標都是預設可空的。
為了橋接適配 Swift,可空需要加nullable
識別符號
eg:
@interface Action : UIButton
+ (instancetype)actionWithTitle:(nullable NSString *)title handler:(void (^ __nullable)(Action *action))handler;
@property (nullable, nonatomic, readonly) NSString *title;
@property (nonatomic, getter=isEnabled) BOOL enabled;
@end
生成的介面檔案如下:
open class Action : UIButton {
public convenience init!(title: String?, handler: ((Action?) -> Swift.Void)? = nil)
open var title: String? { get }
open var isEnabled: Bool
}
Unwrapping
使用?
來訪問一個Optional值,let rooms = person.residence?.numberOfRooms
注意:當未對可選值做處理時,Xcode會在可選值上建議你用!
強制解包,不要聽它的
注意:當未對可選值做處理時,Xcode會在可選值上建議你用!
強制解包,不要聽它的
注意:當未對可選值做處理時,Xcode會在可選值上建議你用!
強制解包,不要聽它的
let john = Person()
let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error
正確姿勢:
宣告
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let person = Person()
使用 guard let
let john = Person()
guard let roomCount = john.residence?.numberOfRooms else {
print("Unable to retrieve the number of rooms.")
}
print("John's residence has \(roomCount) room(s).")
// Prints "Unable to retrieve the number of rooms."
或者if let
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."
建議用guard
,在流程上更能表現出解包失敗是非預期行為,而且減少了程式碼層級。
Default Value
let rooms = person.residence?.numberOfRooms ?? 5 // output: 5
Error Handling
https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html
二級指標
@interface PDModuleManager (Handle)
- (id)invokeAction:(NSString *)action forModule:(NSString *)module withArguments:(NSArray *)arguments error:(NSError **)error;
@end
OC的(NSError **)
會被自動轉換為throws -> Any
。
open func invokeAction(_ action: String!, forModule module: String!, withArguments arguments: [Any]!) throws -> Any
雖然 Foundation 裡有定義 public typealias NSErrorPointer = AutoreleasingUnsafeMutablePointer<NSError?>?
來指代二級指標,但是由於上述的轉換,所以並不常用
Enum - the modern way
public enum MoyaError: Swift.Error {
/// Indicates a response failed to map to an image.
case imageMapping(Response)
/// Indicates a response failed to map to a JSON structure.
case jsonMapping(Response)
/// Indicates a response failed to map to a String.
case stringMapping(Response)
/// Indicates a response failed to map to a Decodable object.
case objectMapping(Swift.Error, Response)
}
func canThrowErrors() throws -> String
func cannotThrowErrors() -> String
do {
let urlRequest = try endpoint.urlRequest()
closure(.success(urlRequest))
} catch MoyaError.requestMapping(let url) {
closure(.failure(MoyaError.requestMapping(url)))
} catch MoyaError.parameterEncoding(let error) {
closure(.failure(MoyaError.parameterEncoding(error)))
} catch {
closure(.failure(MoyaError.underlying(error, nil)))
}
Type Casting
https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html
Downcasting
for item in library {
if let movie = item as? Movie {
print("Movie: \(movie.name), dir. \(movie.director)")
} else if let song = item as? Song {
print("Song: \(song.name), by \(song.artist)")
}
}
// Movie: Casablanca, dir. Michael Curtiz
// Song: Blue Suede Shoes, by Elvis Presley
// Movie: Citizen Kane, dir. Orson Welles
// Song: The One And Only, by Chesney Hawkes
// Song: Never Gonna Give You Up, by Rick Astley
Type Casting for Any and AnyObject
var things = [Any]()
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
things.append({ (name: String) -> String in "Hello, \(name)" })
for thing in things {
switch thing {
case 0 as Int:
print("zero as an Int")
case 0 as Double:
print("zero as a Double")
case let someInt as Int:
print("an integer value of \(someInt)")
case let someDouble as Double where someDouble > 0:
print("a positive double value of \(someDouble)")
case is Double:
print("some other double value that I don't want to print")
case let someString as String:
print("a string value of \"\(someString)\"")
case let (x, y) as (Double, Double):
print("an (x, y) point at \(x), \(y)")
case let movie as Movie:
print("a movie called \(movie.name), dir. \(movie.director)")
case let stringConverter as (String) -> String:
print(stringConverter("Michael"))
default:
print("something else")
}
}
// zero as an Int
// zero as a Double
// an integer value of 42
// a positive double value of 3.14159
// a string value of "hello"
// an (x, y) point at 3.0, 5.0
// a movie called Ghostbusters, dir. Ivan Reitman
// Hello, Michael
Extensions
https://docs.swift.org/swift-book/LanguageGuide/Extensions.html
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}
Protocols
protocol Vehicle {
var numberOfWheels: Int { get } //readonly
var color: UIColor { get set } //read-write
}
Optional
https://stackoverflow.com/questions/48837915/optional-protocol-methods-in-swift-without-using-objc
OP1
You can define default func implementation by:
protocol Opt {
func requiredFunc()
func optionalFunc()
}
extension Opt {
func optionalFunc() {}
}
With this you don't have to implement optionalFunc() in classes conforming to Opt, because they already have their default implementation.
OP2
Using @objc in swift, we can create an optional methods inside protocol like
@objc protocol MyProtocol {
@objc optional func anOptionalMethod()
}
Declaring Protocol Adoption with an Extension
struct Hamster {
var name: String
var textualDescription: String {
return "A hamster named \(name)"
}
}
extension Hamster: TextRepresentable {}
Access Control
- Open
- Public
- Internal
- File-private
- Private
相關文章
- Git Cheat Sheet 中文版Git
- Axios 作弊表(Cheat Sheet)iOS
- ChatGPT Prompting Cheat Sheet備忘ChatGPT
- XSS Filter Evasion Cheat Sheet 中文版Filter
- 基於 emoji-toolkit 的 Emoji cheat sheet 速查表
- Advanced-Swift中文版Swift
- Collections in Swift 4Swift
- 【譯】回顧Swift 3, 展望Swift 4Swift
- swift4 kvcSwift
- Swift 4 中的字串Swift字串
- UNIX Quick Reference SheetUI
- excel合併sheetExcel
- Swift 4 遷移踩坑Swift
- swift學習筆記《4》Swift筆記
- Swift 4 弱引用實現Swift
- Swift 4 - 模仿今日頭條Swift
- Swift 4 中的泛型Swift泛型
- swift4 常用屬性Swift
- [swift 進階 advanced swift]讀書筆記-第六章:字串 C7P1 不再固定寬度Swift筆記字串
- 用Pandas讀寫Excel檔案-輸出單sheet和多sheetExcel
- 使用Qt Style Sheet(1)QT
- PermissionScope Swift4 相容問題Swift
- 一個cheat命令 == Linux命令小抄大全Linux
- 關於EasyExcel的資料匯入和單sheet和多sheet匯出Excel
- Swift 4 前後 KVO 的變化Swift
- Swift 4新知:KVC和KVO新姿勢Swift
- Swift4 的變化列舉Swift
- Swift4類和結構(二)Swift
- Swift 4 踩坑之 Codable 協議Swift協議
- 在 Red Hat Advanced Server 4 上安裝 Oracle 10.2.0.1 RAC (zt)ServerOracle
- Oracle Advanced SecurityOracle
- ffmpeg Advanced options
- [LeetCode] Excel Sheet Column NumberLeetCodeExcel
- C#新增多個Sheet表C#
- 《Swift進階》ReadingNotes_4Swift
- 更新swift4所遇到的問題Swift
- Cerbero Suite Advanced 5UI
- Advanced Index CompressionIndex