- 輸出格式化
- Options
- 數(shù)組 enumerate
- 類型編碼 @encode
- C 代碼調(diào)?和 @asmname
--
輸出格式化
OC中使用%@、%g、%d等進行輸出格式化。
Swift支持的輸出方法print支持字符串插值。字符串插值時直接使用類型的Streamable、Printable、DebugPrintable協(xié)議(按先后順序,前面的沒有實現(xiàn)的話就用后面的)中的方法返回的字符串并進行打印。
打印Double 保留兩位小數(shù)如下
extension Double {
func formatPrint(_ f: String) -> String {
return String(format:"%\(f)f",self)
}
}
let b = 2.345
_ = String(format:"%.2f",b) // 2.35
print("b is \(b)") //2.345
let pr = b.formatPrint(".2")
print("pr is \(pr)") //2.35
--
Options
OC中的Options
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
UIRectCornerTopLeft = 1 << 0,
UIRectCornerTopRight = 1 << 1,
UIRectCornerBottomLeft = 1 << 2,
UIRectCornerBottomRight = 1 << 3,
UIRectCornerAllCorners = ~0UL
};
// 可以使用 `|` `&` 這樣的按位邏輯符對這些選項操作,因為Options的定義都是這么按位錯開的。
[UIBezierPath bezierPathWithRoundedRect:self.view.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(5, 5)];
Swift中的Options是一個滿足OptionSet協(xié)議的struct,以及一組靜態(tài)的get屬性
public struct UIRectCorner : OptionSet {
public init(rawValue: UInt)
public static var topLeft: UIRectCorner { get }
public static var topRight: UIRectCorner { get }
public static var bottomLeft: UIRectCorner { get }
public static var bottomRight: UIRectCorner { get }
public static var allCorners: UIRectCorner { get }
}
UIBezierPath.init(roundedRect: self.view.frame, byRoundingCorners: [.topLeft,.topRight], cornerRadii: CGSize.init(width: 5, height: 5))
--
數(shù)組 enumerate
快速枚舉數(shù)組的EnumerateGenerator,元素是一個元組
let arr = [2,3,4,56,7,8,9]
var result = 0
for (index, num) in arr.enumerated() {
result += num
if index == 4 {
break
}
}
print("result is \(result)")
--
類型編碼 @encode
類型編碼是編譯器對每種類型都給定了一個字符串作為該類型唯一的編碼
OC中獲取某種類型編碼使用@encode()
char *stringEncode = @encode(NSString);//NSString=#
char *intEncode = @encode(int);//i
Swift使用自己的Metatype處理類型,并且在運行時保留這些類型的信息,所以swift沒有保留這個關鍵字。swift中就不能獲取任何類型的類型編碼了,但是可以通過NSValue的objcType屬性獲取對應值的類型指針。
class NSValue {
var objCType: [UnsafePointer]<[Int8] { get }
}
let range = NSRange.init()
let rValue = NSValue.init(range: range).objCType //{_NSRange=QQ}
print(String(validatingUTF8: rValue) ?? "")
let pi: Double = 3.14159
let dValue = NSNumber.init(value: pi).objCType // d
print(String(validatingUTF8: dValue) ?? "")
--
C 代碼調(diào)?和 @asmname
-
Darwin涵蓋了絕大數(shù)C標準庫中的內(nèi)容。導入使用import Darwin。實際編碼中,UIKit包含了Foundation,Foundation又包含了Darwin,不用我們手動再導入了。

Darwin中包含了C標準庫中大多數(shù)內(nèi)容
swift做好了
Darwin中的類型的自動轉(zhuǎn)換對應,可以直接使用Swift的類型。
做好了`Darwin`中的類型的自動轉(zhuǎn)換對應
-
對于自己創(chuàng)建的C文件,導入的時候同swift調(diào)用OC代碼一樣。建立一個bridge文件,在橋文件中導入頭文件
// test.h void doSomething(); // test.m void doSomething() { // do something } //Module-Bridging-Header.h #import "test.h" // a.swift doSomething() -
可以使用
@asmname符號,通過方法名字,將C函數(shù)直接映射為swift中的函數(shù)。這時候就不用橋文件了。//將 C 的 test ?法映射為 Swift 的 c_test ?法 @asmname("doSomething") func c_test() -> Void
除了上面一個作用外,@asmname還承擔著和@objc的‘重命名swift類中類和方法名’類似的任務,可以將C語言中不認的swift元素字符轉(zhuǎn)為ASCII碼,以便使用。