WWDC 2014 Notes


Session 407

id and AnyObject

  • Runtime Check

Swift中的AnyObject相当于OC中的id。对于id来说,可在运行时接收消息:

if([object respondsToSelector:@selector(removeFormSuperview)]){
	[object removeFromSuperview];
}

对应到Swift,使用optional来做运行时的判断

let object:AnyObject = SomeClass()
object.removeFromSuperview?()
  • Downcasting AnyObject
    • AnyObject does not implicity downcast
      let view:UIView = object //error:'AnyObject' cannot be implicitly downcast
    
    • 使用”as”在运行时做类型转化
      let view = object as UIView
    
    • 使用”as?”
      if let view = object as? UIView{
          // view is UIView
      }
    

Implicitly Unwrapped Optionals

  • From WWDC session 407:
    • A value of class type in Swift is never nil
    • Optional types generalize the notion of nil
    • Objective-C does not have a notion of a “never nil” pointer
    • ”!” is an implicitly unwrapped optional
    • Can be tested explicity for nil
    • Can directly access properties/methods of the underlying value
    • Can be implicity converted to its underlying value(e.g. NSDate)
  • 做成员变量:

var date:NSDate!意思是,当使用date的时候,会隐式的unwrap,例如,当用self.date的时候,相当于self.date!。如果datenil,那么会crash。

  • 做参数:

用!声明的参数可以传nil这主要是为了兼容OC,由于OC中name允许为nil,对应到swift中,name要声明为String!类型,才可以接受nil

- (NSString* )type:(NSString* )name operation:(UIDocumentSaveOperation)op;
//swift
func type(name:String!, operation: UIDocumentSaveOperation) -> String!

Protocols

  • Objective-C
@protocol UITableViewDataSource<NSObject>
@optional
- (NSInteger)numberOfSectionsInTableView:(UITableView)tableview;
@required
- (NSInteger)tableView:(UITableView* )tableView numberOfRowsInSection:(NSInteger)section;
@end

@property id<UITableViewDataSource> dataSource;
  • Swift
@objc protocol UITableViewDataSource:NSObjectProtocol{
	func tableView(tableView:UITableView, numberOfRowsInSection: Int) -> Int
	@optional func numberOfSectionsInTableView(tableView:UITableView) -> Int
}
var dataSource: UITableViewDataSource!
  • Downcast via as? to protocol type
if let ds = object as? UITableViewDataSource{
	let rowsInFirstSection = ds.tableView(tableView,numberOfRowsInSection:0)
}

Swift Objects are the OC objects

All Swift classes are “id compatible”

  • Same layout as an Objective-C class
  • Same basic infrastructure(retain/release/class/etc.) inheriate from Objective-C class to make your class directly visible in Objective-c, 继承Objective-C class使其能够被OC运行时发现

getters and setters

var name:String{
	get { return "b" }
	set {}
}

Override the property itself not the getter or setter

  • getter:
override var name:String{
	return "this is my \(self.view) string"
}

@objc

“objc” attribute verifies that the declaration can be used in Objective-C。 objc关键字的作用本质上是让Swift中的某个数据结构(类,方法等)在OC的运行时可见。例如,对于Swift中返回tuple的函数,对于这种类型的Swift函数,编译器会给出错误。

@objc func myGenericMethod<T>(x:T) -> (String,String){...} //error: not expressible in oc

在OC的runtime中改变Swift中的数据结构名称

var enabled: Bool{
	@objc(isEnabled)get{...}
	set{...}
}

这样在OC的runtime中,enable的getter方法就变为了isEnabled

@objc(ABCMyDocument) class MyDocument:UIDocument{

}

Unmanaged Object

Unmanaged enables manual memory management

struct Unmanaged<T:AnyObject>{

	func takeUnretainedValue() -> T
	func takeRetainedValue() -> T
}

Use it to work with unaudited CF APIs

let color = CGColorGetRandomColor().takeUnretainedValue()