Swift 3.1 简明代码

init() { /* ... */ }
init(frame: CGRect, style: UITableViewStyle) { /* ... */ }
let myTableView: UITableView = UITableView(frame: .zero, style: .grouped)
let myTextField = UITextField(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 40.0))
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

用 if let 对可选值进行有值绑定

if let image = UIImage(contentsOfFile: "MyImage.png") {

// loaded the image successfully

} else {

// could not load the image

}
myTextField.textColor = .darkGray

myTextField.text = "Hello world”

myTableView.insertSubview(mySubview, at: 2)

如果你调用的方法是没有参数的,调用时也得加上在点方法后也得加上括号

myTableView.layoutIfNeeded()
var x: Any = "hello" as String

x as? String // String with value "hello"

x as? NSString // NSString with value "hello"

x = "goodbye" as NSString

x as? String // String with value "goodbye"

x as? NSString // NSString with value "goodbye"
let userDefaults = UserDefaults.standard

let lastRefreshDate = userDefaults.object(forKey: "LastRefreshDate") // lastRefreshDate is of type Any?

if let date = lastRefreshDate as? Date {

print("\(date.timeIntervalSinceReferenceDate)")

}

如果你确定类型,可强制解包

let myDate = lastRefreshDate as! Date

let timeInterval = myDate.timeIntervalSinceReferenceDate

如果类型不匹配,就会出现错误

let myDate = lastRefreshDate as! String // Error
var nullableProperty: Any? // 可选值,可空和必有值两种情况

var nonNullProperty: Any // 必有值

var unannotatedProperty: Any! // 未知

func returnsNonNullValue() -> Any // 必有返回值

func takesNonNullParameter(value: Any) // 参数必有值

func returnsNullableValue() -> Any? //可选值的返回值

func takesNullableParameter(value: Any?) 可选值的参数

func returnsUnannotatedValue() -> Any! // 未知返回

func takesUnannotatedParameter(value: Any!) 未知参数
var dates: [Date]

var cachedData: NSCache

var supportedLocales: [String: [Locale]]

class List : NSObject {

func listByAppendingItemsInList(otherList: List) -> List

}

class ListContainer : NSObject {

func listOfValues() -> List

}

extension ListContainer {

func listOfObjects() -> List

}

extension

extension UIBezierPath {

convenience init(triangleSideLength: CGFloat, origin: CGPoint) {

self.init()

let squareRoot = CGFloat(sqrt(3.0))

let altitude = (squareRoot * triangleSideLength) / 2

move(to: origin)

addLine(to: CGPoint(x: origin.x + triangleSideLength, y: origin.y))

addLine(to: CGPoint(x: origin.x + triangleSideLength / 2, y: origin.y + altitude))

close()

}

}

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

OC的block,Swift的闭包closures

void (^completionBlock)(NSData *) = ^(NSData *data) {

// ...

}

let completionBlock: (Data) -> Void = { data in

// ...

}

解决循环引用问题的处理

__weak typeof(self) weakSelf = self;

self.block = ^{

__strong typeof(self) strongSelf = weakSelf;

[strongSelf doSomething];

};

self.closure = { [unowned self] in

self.doSomething()

}

类定义

class Jukebox: NSObject {

var library: Set

var nowPlaying: String?

var isCurrentlyPlaying: Bool {

return nowPlaying != nil

}

class var favoritesPlaylist: [String] {

// return an array of song names

}

init(songs: String...) {

self.library = Set(songs)

}

func playSong(named name: String) throws {

// play song or throw an error if unavailable

}

}

NOTE
You cannot subclass a Swift class in Objective-C. 你不能用OC来实现一个Swift的子类

import UIKit

class MyViewController: UIViewController {

let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {

super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

let action = #selector(MyViewController.tappedButton)

myButton.addTarget(self, action: action, forControlEvents: .touchUpInside)

}

func tappedButton(sender: UIButton?) {

print("tapped button")

}

required init?(coder: NSCoder) {

super.init(coder: coder)

}

}
let string: NSString = "Hello, Cocoa!"

let selector = #selector(NSString.lowercased(with:))

let locale = Locale.current

if let result = string.perform(selector, with: locale) {

print(result.takeUnretainedValue())

}

// Prints "hello, cocoa!"

let array: NSArray = ["delta", "alpha", "zulu"]

// Not a compile-time error because NSDictionary has this selector.

let selector = #selector(NSDictionary.allKeysForObject)

// Raises an exception because NSArray does not respond to this selector.

array.perform(selector)

@objc(Color) OC能访问得到这个Swift类

@objc(Color)

enum Цвет: Int {

@objc(Red)

case Красный

@objc(Black)

case Черный

}

@objc(Squirrel)

class Белка: NSObject {

@objc(color)

var цвет: Цвет = .Красный

@objc(initWithName:)

init (имя: String) {

// ...

}

@objc(hideNuts:inTree:)

func прячьОрехи(количество: Int, вДереве дерево: Дерево) {

// ...

}

}
class Person: NSObject {

var name: String

var friends: [Person] = []

var bestFriend: Person? = nil

init(name: String) {

self.name = name

}

}

let gabrielle = Person(name: "Gabrielle")

let jim = Person(name: "Jim")

let yuanyuan = Person(name: "Yuanyuan")

gabrielle.friends = [jim, yuanyuan]

gabrielle.bestFriend = yuanyuan

#keyPath(Person.name)

// "name"

gabrielle.value(forKey: #keyPath(Person.name))

// "Gabrielle"

#keyPath(Person.bestFriend.name)

// "bestFriend.name"

gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))

// "Yuanyuan"

#keyPath(Person.friends.name)

// "friends.name"

gabrielle.value(forKeyPath: #keyPath(Person.friends.name))

// ["Yuanyuan", “Jim”]

用Swift来定义一个OC类的子类

import UIKit

class MySwiftViewController: UIViewController {

// define the class

}

遵守协议

class MySwiftViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

// define the class

}
let myPersonClass: AnyClass? = NSClassFromString("MyGreatApp.Person”)

托线操作

class MyViewController: UIViewController {

// 属性托线

@IBOutlet weak var button: UIButton!

@IBOutlet var textFields: [UITextField]!

// 事件托线

@IBAction func buttonTapped(sender: AnyObject) {

print("button tapped!")

}

}

IB可视化操作,实践了下感觉如果电脑反应不快,会卡得慌,于是就没有用了,不过很是方便

@IBDesignable

class MyCustomView: UIView {

@IBInspectable var textColor: UIColor

@IBInspectable var iconHeight: CGFloat

// ...

}

定义协议

import UIKit

@objc protocol MyCustomProtocol {

var people: [Person] { get }

func tableView(_ tableView: UITableView, configure cell: UITableViewCell, forPerson person: Person)

@objc optional func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forPerson person: Person)

}

OC对象也能遵守实现这个协议

@interface MyCustomController: UIViewController 

@property (nonatomic, strong) NSArray *people;

@end

@implementation MyCustomController

@synthesize people;

- (void)tableView:(UITableView *)tableView

configure:(UITableViewCell *)cell

forPerson:(Person *)person

{

// Configure cell

}

@end

与Cocoa Frameworks进行操作

import Foundation

let string: String = "abc"

let bridgedString: NSString = string as NSString

let stringLiteral: NSString = "123"

if let integerValue = Int(stringLiteral as String) {

print("\(stringLiteral) is the integer \(integerValue)")

}

// Prints "123 is the integer 123"

import Foundation

let number = 42

let bridgedNumber: NSNumber = number as NSNumber

let integerLiteral: NSNumber = 5

let floatLiteral: NSNumber = 3.14159

let booleanLiteral: NSNumber = true

lazy loading
直接创建的对象

lazy var XML: XMLDocument = try! XMLDocument(contentsOf: Bundle.main.url(forResource: "document", withExtension: "xml")!, options: 0)

var pattern: String

lazy var regex: NSRegularExpression = try! NSRegularExpression(pattern: self.pattern, options: [])

创建完一个对象,还需要对它进行特别属性设置的时候,这样写

lazy var currencyFormatter: NumberFormatter = {

let formatter = NumberFormatter()

formatter.numberStyle = .currency

formatter.currencySymbol = "¤"

return formatter

}()

NOTE

假如这个属性还没有加载,并且被多个线程同时访问,那么不能保证这个属性真的只初始化一次

对于 异常的处理

let fileManager = FileManager.default

let fromURL = URL(fileURLWithPath: "/path/to/old")

let toURL = URL(fileURLWithPath: "/path/to/new")

do {

try fileManager.moveItem(at: fromURL, to: toURL)

} catch let error as NSError {

print("Error: \(error.domain)")

}

do {

try fileManager.moveItem(at: fromURL, to: toURL)

} catch CocoaError.fileNoSuchFile {

print("Error: no such file exists")

} catch CocoaError.fileReadUnsupportedScheme {

print("Error: unsupported scheme (should be 'file://')")

}

代码对比,精简了很多下面

NSFileManager *fileManager = [NSFileManager defaultManager];

NSURL *tmpURL = [fileManager URLForDirectory:NSCachesDirectory

inDomain:NSUserDomainMask

appropriateForURL:nil

create:YES

error:nil];

if (tmpURL != nil) {

// ...

}
let fileManager = FileManager.default

if let tmpURL = try? fileManager.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) {

// ...

}

KVO
使用关键字 dynamic 字来修饰你想要监听变化的这个属性

class MyObjectToObserve: NSObject {

dynamic var myDate = NSDate()

func updateDate() {

myDate = NSDate()

}

}

写一个全局的变量来记录对比操作

private var myContext = 0

在需要开启监听的地方监听,然后重写这个方法 observeValue(for:of:change:context:)
还有一点很重要,对象销毁时在方法 deinit移除监听

class MyObserver: NSObject {

var objectToObserve = MyObjectToObserve()

override init() {

super.init()

objectToObserve.addObserver(self, forKeyPath: #keyPath(MyObjectToObserve.myDate), options: .new, context: &myContext)

}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

if context == &myContext {

if let newValue = change?[.newKey] {

print("Date changed: \(newValue)")

}

} else {

super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)

}

}

deinit {

objectToObserve.removeObserver(self, forKeyPath: #keyPath(MyObjectToObserve.myDate), context: &myContext)

}

}

单例的写法

class Singleton {

static let sharedInstance = Singleton()

}

如果你需要做些额外的事情 ,可以还这样写

class Singleton {

static let sharedInstance: Singleton = {

let instance = Singleton()

// setup code

return instance

}()

}

对于 OC isKindOfClass还有confirmsToProtocal可以用is as?来处理

if object is UIButton {

// object is of type UIButton

} else {

// object is not of type UIButton

}

if let button = object as? UIButton {

// object is successfully cast to type UIButton and bound to button

} else {

// object could not be cast to type UIButton

}

if let dataSource = object as? UITableViewDataSource {

// object conforms to UITableViewDataSource and is bound to dataSource

} else {

// object not conform to UITableViewDataSource

}

自动释放池的运用

import Foundation

autoreleasepool {

// code that creates autoreleased objects.

}

方法可用性的检测

if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {

// Method is available for use.

} else {

// Method is not available.

}

let locationManager = CLLocationManager()

if #available(iOS 8.0, macOS 10.10, *) {

locationManager.requestWhenInUseAuthorization()

}

let locationManager = CLLocationManager()

guard #available(iOS 8.0, macOS 10.10, *) else { return }

locationManager.requestWhenInUseAuthorization()

你也可以定义一个特别的方法在特别的版下特别的平台下运行

@available(iOS 8.0, macOS 10.10, *)

func useShinyNewFeature() {

// ...

}

条件编译

#if DEBUG_LOGGING

print("Flag enabled.")

#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 3.1 简明代码)