日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Swift与Objective-C API交互

發布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Swift与Objective-C API交互 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Swift和Objective-C可以進行互操作,也就是說可以在Objective-C項目中使用Swift代碼,反過來也可以。當然,這種互操作之間最重要的是可以在Swift中調用Objective-C的接口,畢竟目前絕大部分接口都是通過Objective-C提供的。

初始化

在Swift中實例化一個Objective-C的類時,可以用Swift語法調用它的一個初始化器。Objective-C的初始化方法被分割成關鍵字。例如“initWith”變成“init”,而剩下的部分作為方法的參數名。

Objective-C的代碼:

UITableView?*myTableView?=?[[UITableView?alloc]?initWithFrame:?CGRectZero?style:?UITableViewStyleGrouped];

對應的Swift代碼為:

let?myTableView:?UITableView?=?UITableView(frame:?CGRectZero,?style:?.Grouped)

在Swift中不需要調用alloc方法,它會自動處理對象的創建功能。注意:Swift不會顯式的調用init方法。

定義變量或者常量的時候,可以省略它的類型,Swift會自動識別。

let?myTextField?=?UITextField(frame:?CGRect(0.0,?0.0,?200.0,?40.0))

為了方便起見,Objective-C的工廠方法被映射為Swift中的初始化器。例如:

UIColor?*color?=?[UIColor?colorWithRed:?0.5?green:?0.0?blue:?0.5?alpha:?1.0];

轉換為Swift:

let?color?=?UIColor(red:?0.5,?green:?0.0,?blue:?0.5,?alpha:?1.0)

屬性訪問

在Objective-C和Swift中訪問屬性都是使用點操作符。

myTextField.textColor?=?UIColor.darkGrayColor() myTextField.text?=?"Hello?world"if?myTextField.editing?{myTextField.editing?=?false}

訪問和設置屬性的時候不需要使用圓括號,上面darkGrayColor之所以有括號,是因為調用的是UIColor的類方法,而不是屬性。

Objective-C中不需要參數并且有一個返回值的方法,可以被當作隱含的獲取方法(getter),從而使用點操作符。但是在Swift中點操作符只能訪問Objective-C中使用@property定義的屬性。

方法調用

在Swift中使用點操作符調用Objective-C中的方法。

Objective-C的方法在Swift中調用的時候,它的第一部分成為Swift的基本方法出現在括號之前。然后函數的第一個參數沒有名字,剩下的部分作為Swift函數對應的參數名稱。
Objective-C語法:

[myTableView?insertSubview:?mySubview?atIndex:?2];

Swift代碼:

myTableView.insertSubview(mySubview?atIndex:?2)

調用無參的方法:

myTableView.layoutIfNeeded()

兼容id類型

Swift包含一個叫AnyObject的協議,與Objective-C中的id類似,可以表示任意類型的對象。AnyObject協議允許你在利用無類型對象的靈活性的同時保持類型安全。
你可以給AnyObject類型的變量賦任意的值:

var?myObject:?AnyObject?=?NSData()

可以直接方法AnyObject類型對象的任意屬性和方法,而不需要進行強制類型轉換。

let?dateDescription?=?myObject.descriptionlet?timeSinceNow?=?myObject.timeIntervalSinceNow

由于AnyObject類型的變量的類型需要到運行時才能確定,因此可能會導致不安全的代碼。特別是你可以訪問一個不存在的屬性或者方法,它只是在運行時報錯。

myObject.characterAtIndex(5) //crash,?myObject?doesn't?respond?to?that?method

在進行類型轉換的時候,不一定轉換成功,因此Swift返回的是一個Optional值。你可以檢查是否轉換成功。

let?userDefaults?=?NSUserDefaults.standardUserDefaults()let?lastRefreshDate:?AnyObject??=?userDefault.objectForKey("LastRefreshDate")if?let?date?=?lastRefreshDate?as??NSDate?{println("\(date.timeIntervalSinceReferenceDate)") }

如果你能夠確定對象的類型,并且不為nil,可以使用as操作符進行強制轉換。

let?myDate?=?lastRefreshDate?as?NSDatelet?timeInterval?=?myDate.timeIntervalSinceReferenceDate

nil對象

Objective-C中使用nil來表示引用一個空對象(null)。Swift中所有的值都不會為nil。如果需要表示一個缺失的值,可以使用Optional。

由于Objective-C不能確保所有值都非空,因此Swift將Objective-C中引入的方法的參數和返回值都用Optional表示。在使用Objective-C對象之前,應該檢查它們是否存在。

擴展

Swift的擴展與Objective-C的類別有點類似。擴展能夠為已有類、結構體、枚舉等增加行為。

下面是給UIBezierPath添加擴展:

extension?UIBezierPath?{????class?func?bezierPathWithTriangle(length:?Float,?origin:?CGPoint)?->?UIBezierPath?{????????let?squareRoot?=?Float(sqrt(3))????????let?altitude?=?(squareRoot?*?length)?/?2let?myPath?=?UIBezierPath()myPath.moveToPoint(orgin)myPath.addLineToPoint(CGPoint(length,?origin.x))myPath.addLineToPoint(CGPoint(length?/?2,?altitude))myPath.closePath()return?myPath} }

可以使用擴展增加屬性(包括類屬性或靜態屬性)。不過這些屬性只能是通過計算得來,而不能進行存儲。下面給CGRect添加一個area屬性:

extension?CGRect?{var?area:?CGFloat?{return?width?*?height} }let?rect?=?CGRect(x:?0.0,?y:?0.0,?width:?10.0,?height:?50.0) let?area?=?rect.area //area:?CGFloat?=?500.0

使用擴展可以在不創建子類的情況下讓現有的類響應某個協議。需要注意的是,擴展不能覆蓋已有的方法和屬性。

閉包

Objective-C中的Block 被自動導入為Swift的閉包。例如:

void?(^completionBlock)(NSData?*,?NSError?*)?=?^(NSData?*data,?NSError?*error)?{????/*?...?*/}

在Swift 中對應為:

let?completionBlock:?(NSData,?NSError)?->?void?=?{data,?error?in?/*?...?*/}

Swift的閉包和Objective-C中的Block是兼容的,可以在Swift中給Objective-C的方法傳遞閉包來代替Block對象。

閉包和Block對象有一點不同,里面的變量是可變的,也就是說與__block修飾的變量行為相同。

對象比較

Swift中有兩種對象比較的方式。第一種是相等(==)(equality),用來比較兩個對象的內容是否相同。第二種是恒等(===)(identity),比較兩個變量或者常量是否引用同一個對象。

NSObject只能比較是否引用了同一個對象(恒等),如果要比較內容是否相同,應該實現isEqual:方法。

Swift類型兼容性

定義一個繼承自NSObject或者其他Objective-C的類,它自動與Objective-C兼容。如果你不需要將Swift對象導入Objective-C代碼的話,沒必要關注類型的兼容性。但是如果在Swift中定義的類不是Objective-C類的子類,在Objective-C中使用的時候,需要用@objc進行說明。

@objc使得Swift的API可以在Objective-C和它的運行時中使用。當使用@IBOutlet、@IBAction或者@NSManaged等屬性時,自動添加@objc屬性。

@objc還可以用來指定Swift中的屬性或方法在Objective-C中的名字,比如Swift支持Unicode名字,包括使用中文等Objective-C不兼容的字符。還有給Swift中定義的函數指定一個Selectorde名字。

@objc(Squirrel)class?長沙戴維營教育?{@objc(hideNuts:inTree:)func?歡迎光臨(Int,?姓名:?String)?{????????/*?...?*/} }

當@objc(<#name#>)屬性作用在Swift的類上時,這個類在Objective-C的使用不受命名空間的限制。同樣,在Swift中解歸檔Objective-C歸檔的對象時,由于歸檔對象中存放有類名,因此需要在Swift中用@objc<#name>說明Objective-C的類名。

Objective-C選擇器(Selector)

Objective-C的選擇器是方法的一個引用。在Swift中對應的是Selector結構體。使用字符串字面量可以構建一個選擇器對象,如let mySelector: Selector = "tappedButton:"。由于字符串字面常量可以自動轉換為選擇器對象,因此可以在任何需要傳遞選擇器的地方使用字符串字面常量。

import?UIKitclass?MyViewController:?UIViewController?{????let?myButton?=?UIButton(frame:?CGRect(x:?0,?y:?0,?width:?100,?height:?50))init(nibName?nibNameOrNil:?String!,?bundle?nibBundleOrNil:?NSBundle!){super.init(nibName:?nibName,?bundle:?nibBundle)myButton.targetForAction("tappedButton:",?withSender:?self)}func?tappedButton(sender:?UIButton!)?{println("tapped?button")} }

提示
performSelector:以及相關的調用選擇器的方法沒有被引入到Swfit中來,因為它們不是完全安全的。

如果Swift類繼承自Objective-C的類,則它里面的方法和屬性都能夠作為Objective-C的選擇器使用。而如果不是Objective-C的子類,需要使用@objc屬性修飾,這個在前面的Swift類型兼容性中有描述。


轉載于:https://blog.51cto.com/diveinedu/1623220

總結

以上是生活随笔為你收集整理的Swift与Objective-C API交互的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。