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<AnyObject, NSDiscardableContent>

var supportedLocales: [String: [Locale]]

class List<T: NSCopying> : NSObject {

func listByAppendingItemsInList(otherList: List<T>) -> List<T>

}

class ListContainer : NSObject {

func listOfValues() -> List<NSValue>

}

extension ListContainer {

func listOfObjects() -> List<NSCopying>

}

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<String>

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<String>(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 <MyCustomProtocol>

@property (nonatomic, strong) NSArray<Person *> *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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容