美文网首页iOS开发文集
Swift 3.1 简明代码

Swift 3.1 简明代码

作者: 十一岁的加重 | 来源:发表于2017-04-13 22:37 被阅读12769次
    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
    
    

    相关文章

      网友评论

        本文标题:Swift 3.1 简明代码

        本文链接:https://www.haomeiwen.com/subject/hruiattx.html