你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> swift3.0和Objective

swift3.0和Objective

編輯:IOS開發基礎

QQ截圖20160620151152.png

投稿文章,作者:ZeroJ(Gitbub)

前言:

Swift3.0出來後, 可以看到改變很大, 和cocoa, Foundation...的交互也變得更方便了, 同時Swift編寫的應用適配到iOS 7, 所以, 我們可以相信: 在未來使用swift的情況會逐漸增加了, 同時會涉及到OC和Swift在項目中並存的情況, 這裡我重新讀了官方的'Using swift with Cocoa and Objective-C(swift3)'的文檔, 記錄了一些個人覺得比較常用的筆記, 請大家選擇性閱讀(裡面的代碼 均來自文檔)

  • OC的初始化方法在Swift中被引為

 init(...) --- 如果初始化不會失敗
 init?(...) --- 如果初始化可能失敗
 init!(...) --- 否則
  • oc中的property裡的(getter==, setter==)將會被swift忽略

  • id對應Anyobject 但是所有的Anyobject在swift中是可選值, 如果之前的值為可選值, 在被設置為Anyobject後就是多重可選值了

  • oc中的屬性被標記為

nullable -> 在swift中相當於 ?
nonnull -> 在swift中相當於 非可選屬性
未標記 -> 在swift中相當於 !
  • oc中的輕量級泛型也是對應與swift中的泛型

@property NSArray *dates
對應於  var dates: [Date]
  • swift 中的閉包默認捕獲變量的方式相當於 oc中block中捕獲被標記為 __block的變量方式 -> 就是說 閉包捕獲到的是變量的指針

  • swift中只要不是在多線程中, 建議使用[unowned self]來避免循環引用, 多線程中, 建議使用[weak self]

  • == 操作符相當於oc中的isEqual: --- 即比較內容是否相等;=== 相當於oc中的指針比較

  • 繼承自NSObject的子類如果重寫了isEquals:方法, 應當提供 hash 這個屬性

  • 不能在oc中繼承swift的class

  • 如果在swift中遇到oc中不支持的命名 可以利用 @objc(name)為他(屬性 枚舉, 方法名...)名個別名

  • @nonobjc 用來標記oc中不支持的

  • dynamic 將屬性或者方法標記為dynamic就是告訴編譯器把它當作oc裡的屬性或方法來使用(runtime),

  • 當需要使用 KVO 或者 runtime的時候需要這樣處理

  • 當使用oc的 perform(selector, with:)方法的時候會返回一個可選值(指向AnyObject的指針);但是使用perform(:on:with:waitUntilDone:modes:) and perform(:with:afterDelay:)不會返回可選值

  • 使用 #keyPath() 可以轉換為string, #keyPath(class.property) == "property"

  • 可用於KVC 例如person.value(forKey: #keyPath(Person.name)) = person.name

  • 但是測試了下不能修改swift中的只讀屬性 不知道有什麼方便的用處

  • NSClassFromString("MyFramework.MyClass")

  • @IBDesignable 用在class(UIView的子類)聲明的前面, 然後就可以在storyBoard中的inspector編輯它;@IBInspectable 用在(UIView的子類)的屬性前面, 然後就可以在storyBoard中的inspector編輯它 ,就想系統提供的可以設置顏色,字體...

  • swift中的屬性默認是strong類型, 只有可選類型才能被標記為weak

  • oc中的 copy屬性 轉換為swift中的@NSCopying 必須遵守NSCoding協議

  • 使用Core Data的時候所有的屬性和方法需要標記為 @NSManaged

  • 文檔中指出"The corresponding reference types can be accessed with their original NS class name prefix."但是beta版本中不能很好的使用NS開頭的

  • 在oc和swift的橋接類型之間 直接使用 as 可以相互轉換

  • 因為swift中的String和NSString使用的編碼方式不一樣,所以在swift中要對string使用索引的時候 不能直接使用 Int 或者NSRange

  • 需要使用String.Index and Range

  • swift會將Double, Int, Bool, Uint, Float和NSNumber橋接, 所以可以直接將

  • 這些類型的值使用 as NSNumber轉換為NSNumber, 但是逆向進行是得到的可選值 as?

  • Foundation 和Core Foundation 之間的類型有toll-free bridge('免費橋')

  • Foundation中的常量, 在swift中被換為類嵌套的枚舉:NSJSONReadingOptions ----- >> JSONSerialization.ReadingOption

  • swift中使用 Core Foundation

  • 如果使用swift處理過的函數不用我們手動管理內存分配;否則需要我們處理

  • 區分的方式: 當返回值是 Unmanaged的時候說明需要我們處理

  • 處理方法: 在使用返回的值之前調用他對應的takeUnretainedValue() 或takeRetainedValue()即可

  • 例如let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()

  • swift中Core Foundation裡的類型 Ref後綴被去掉了 例如 CFTypeRef -> CFType

  • 在oc的方法 使用 NS_SWIFT_NOTHROW , 將不會使用swift的異常拋出機制

  • swift中直接使用 is 來實現oc中isKindOfClass: 的功能

  • swift中使用kvo的條件: 1.必須繼承自NSObject 2. 被觀察的屬性 要被標記為 dynamic

  • swift 中的單例很簡單:

class Singleton {
  static let sharedInstance = Singleton()
}

或者

class Singleton {
  static let sharedInstance: Singleton = {
      let instance = Singleton()
      // setup code
      return instance
  }()
}
  • swift和C的交互: c的函數在swift中均為全局函數

  • 使用CF_SWIFT_NAME 這個宏可以將c中的屬性或者函數轉換為swift中

eg:

Color ColorCreateWithCMYK(float c, float m, float y, float k) CF_SWIFT_NAME(Color.init(c:m:y:k:));

對應為swift中

extension Color {
  init(c: Float, m: Float, y: Float, k: Float)
}
  • c語言中的枚舉 如果使用了NS_ENUM定義, 則在swift中被處理為對應的枚舉

  • 如果沒有使用NS_ENUM定義, 則被處理為結構體

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
 UITableViewCellStyleDefault,
 UITableViewCellStyleValue1,
 UITableViewCellStyleValue2,
 UITableViewCellStyleSubtitle
};
//對應與
enum UITableViewCellStyle: Int {
  case `default`
  case value1
  case value2
  case subtitle
}
typedef enum {
 MessageDispositionUnread = 0,
 MessageDispositionRead = 1,
 MessageDispositionDeleted = -1,
} MessageDisposition;

對應與

struct MessageDisposition: RawRepresentable, Equatable {}
var MessageDispositionUnread: MessageDisposition { get }
var MessageDispositionRead: MessageDisposition { get }
var MessageDispositionDeleted: MessageDisposition { get }

c中的被NS_OPTIONS修飾的枚舉, 在swift中是OptionSet類型, -> 即可以使用數組方式選多個值

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
      UIViewAutoresizingNone                 = 0,
      UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
      UIViewAutoresizingFlexibleWidth        = 1 << 1,
      UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
      UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
      UIViewAutoresizingFlexibleHeight       = 1 << 4,
      UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

對應與

public struct UIViewAutoresizing : OptionSet {
  public init(rawValue: UInt)
  public static var flexibleLeftMargin: UIViewAutoresizing { get }
  public static var flexibleWidth: UIViewAutoresizing { get }
  public static var flexibleRightMargin: UIViewAutoresizing { get }
  public static var flexibleTopMargin: UIViewAutoresizing { get }
  public static var flexibleHeight: UIViewAutoresizing { get }
  public static var flexibleBottomMargin: UIViewAutoresizing { get }
}
  • 在swift中直接使用  let resize = [. flexibleLeftMargin, . flexibleWidth...]

  • 在swift中全局變量和存儲屬性都被保證只初始化一次,所以用來當作OC裡面的#define定義的常量。同時swift全局函數可以當作OC裡#define定義的復雜宏(類似函數)

  • swift中的條件編譯 自定義編譯符的方法(例如: DEBUG_LOGGING)

  • 首先在project 的設置裡面設置swift -D DEBUG_LOGGING to set the DEBUG_LOGGING

  • 然後使用 #if DEBUG_LOGGING // 操作 #endif

#if arch(arm) || arch(arm64)
#if swift(>=3.0)
print("Using Swift 3 ARM code")
#else
print("Using Swift 2.2 ARM code")
#endif
#elseif arch(x86_64)
print("Using 64-bit x86 code.)
#else
print("Using general code.")
#endif
  • swift中使用指針的方式

  • 使用inout方式 &變量

  • 使用UnsafePointer或者UnsafeMutablePointer

例如這個函數接受的參數可以傳許多種

let x: Float = 0
func takesAPointer(_ p: UnsafePointer!) {
// ...
}
takesAPointer(&x)
takesAPointer([0.0,1.0])
  • 在swift中申明oc中的包含可選實現方法的協議時需要在協議和方法前都標記objc

@objc public protocol MySwiftProtocol {
// 必須實現
  func requiredMethod()
  @objc optional func optionalMethod()
}
  • 將oc的方法或者屬性使用NS_SWIFT_NAME()可以為他們在swift中命一個別名

  • 將oc的方法或使用 NS_SWIFT_UNAVAILABLE()可以讓他在swift中不可用

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved