美文网首页
Swfit语法tips

Swfit语法tips

作者: 黑化肥发灰 | 来源:发表于2017-10-06 11:46 被阅读32次

    关于函数和闭包的介绍

    image.png image.png

    在Swift中定义的Enum,OC中使用

    Swift中定义如下,注意@objc

    import Foundation
    import IQKeyboardManagerSwift
    
    @objc enum RotateState: Int {
        case RotateStateDisable
        case RotateStateEnable
        case RotateStateCameraLive
    }
    
    class SystemInitManager: NSObject {
        
        @objc var allowRotation: RotateState = .RotateStateDisable
    
        //MARK: 单例
        @objc static let shared = SystemInitManager()
        private override init() {
            super.init()
        }
        
        func config() {
            ZYNetworkManager.sharedInstance()
            IQKeyboardManager.sharedManager().enable = true
        }
    }
    

    在OC中使用方法如下:

        SystemInitManager.shared.allowRotation = RotateStateRotateStateEnable;
    

    不能用OC的写的类去继承Swift的类


    stackoverflow

    init 与 viewDidLoad调用顺序

    参考链接
    init 与 viewDidLoad调用顺序在UITabBarController及其之类中,viewDidLoad调用在先;在其他Controller中,init调用在先;

    判断是否是iPhone X方法

         class func isIphoneX() -> Bool {
            let app = UIApplication.shared
            let statusBar = app.value(forKey: "statusBar") as AnyObject
            guard let _ = NSClassFromString("UIStatusBar_Modern") else {
                return false
            }
            if statusBar.isKind(of: NSClassFromString("UIStatusBar_Modern")!) {
                return true
            } else {
                return false
            }
        }
    

    Attention

    服务器获取的JSON在Swift中会被表示成一个[String: Any]的字典

    Dictionary 为 [:] 和 nil的时候

            let dic1: [String: String] = [:]
            let dic2: [String: String]? = nil
            
            ZYPrint(markStr: "dic1.count", message: dic1.count)
            ZYPrint(markStr: "dic2.count", message: dic2?.count)
            
            if dic1.isEmpty {
                print("dic1.isEmpty")
            }
            
            if (dic2?.isEmpty)! {
                print("dic2.isEmpty")
            }
    

    输出如下

    ****************************************
    dic1.count:
    0
    
    ****************************************
    dic2.count:
    nil
    dic1.isEmpty
    
    

    最后还会crash


    UserDefaults

    Objective-C中需要调用 synchronize 方法进行同步, 但是在Swift中已经废弃了该方法, 所以不需要手动去调用.
    -synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release.

    给系统类添加属性

    参考Alamofire

    extension URLSession {
        private struct AssociatedKeys {
            static var managerKey = "URLSession.ServerTrustPolicyManager"
        }
    
        var serverTrustPolicyManager: ServerTrustPolicyManager? {
            get {
                return objc_getAssociatedObject(self, &AssociatedKeys.managerKey) as? ServerTrustPolicyManager
            }
            set (manager) {
                objc_setAssociatedObject(self, &AssociatedKeys.managerKey, manager, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
    

    判断是否是iPhone X

    注意这里判断是否属于某个类型的方法

    func isIphoneX() -> Bool {
        
        let app = UIApplication.shared
        let statusBar = app.value(forKey: "statusBar") as! UIView
        guard let statusClass = NSClassFromString("UIStatusBar_Modern") else {
            return false
        }
        if statusBar.isKind(of: statusClass) {
            return true
        } else {
            return false
        }
    }
    
    

    as & as! & as?

    http://blog.csdn.net/h454036111/article/details/49151933
    一,as
    摘自中文api的话:仅当一个值的类型在运行时(runtime)和as模式右边的指定类型一致 - 或者是该类型的子类 - 的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成as
    模式左边指定的模式。
    首先是运行时 就不多说了 ,重要的是 as 应用条件有2种情况:
    1,和 "as" 右边类型一致
    2,是右边类型的子类(这种情况在java里叫向上转型)
    事例代码如下:


    二,as!
    上例中 第二种情况 2,是右边类型的子类 如果 碰到as 左边类型是右边类型的父类则会报错!(as不可以用于父类转子类,用java话说,不支持向下转型),由此可用as!(强转)

    编译器也会提示你用as!, as!强转如果类型不符合会报错。
    三,as?
    as? 相当于optional类型,如果转换失败返回nil。
    上代码!

    定义属性有些可以不用加?

    看看这里返回的方式


    class PageContentView: UIView {
        
        // MARK:- 定义属性
        fileprivate var childVcs : [UIViewController]
        fileprivate weak var parentViewController : UIViewController?
        fileprivate var startOffsetX : CGFloat = 0
        fileprivate var isForbidScrollDelegate : Bool = false
    // weak只能修饰可选类型
        weak var delegate : PageContentViewDelegate?
        
        // MARK:- 懒加载属性,
        fileprivate lazy var collectionView : UICollectionView = {[weak self] in //闭包里面self 加weak
            // 1.创建layout
            let layout = UICollectionViewFlowLayout()
            layout.itemSize = (self?.bounds.size)! // 可选链返回的一定是可选类型,所以这里要解包,一定有值,所以强制解包!
            layout.minimumLineSpacing = 0
            layout.minimumInteritemSpacing = 0
            layout.scrollDirection = .horizontal
            
            // 2.创建UICollectionView
            let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
            collectionView.showsHorizontalScrollIndicator = false
            collectionView.isPagingEnabled = true
            collectionView.bounces = false
            collectionView.dataSource = self
            collectionView.delegate = self
            collectionView.scrollsToTop = false
            collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: ContentCellID)
            
            return collectionView
        }()
        
        // MARK:- 自定义构造函数
        init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController?) {
            self.childVcs = childVcs
            self.parentViewController = parentViewController
            
            super.init(frame: frame)
            
            // 设置UI
            setupUI()
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    }
    
    

    关于for循环

    for _ in 0..<4 {
    }
    
    for view in cell.contentView.subviews {
    }
    
    for (index, value ) in array {
    }
    这三个替代以前的
    for (int i = 0,  i < array.count, i++)  {
    }
    

    cell 注册相关

    以后还是注册一下比较好,养成习惯

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            /*代码创建,并且没有注册cell的情况下,用dequeueReusableCell(withIdentifier identifier: String) -> UITableViewCell?
             如果已经注册了,或者用的xib,就使用dequeueReusableCell(withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell
             */
            //??空合运算符,a ?? b,对可选类型a进行判断,为nil默认值为b,不为空就解封
            let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: reuseIdentifier)
            let text = datas[indexPath.row]
            
            cell.textLabel?.text = text
            cell.textLabel?.textColor = .white
            cell.textLabel?.font = UIFont(name: fontNames[fontNumber], size: 24)
            cell.backgroundColor = .black
            
            return cell
        }
    

    宏定义

    swift中是不能使用宏定义语法的,但是因为命名空间的缘故,我们可以给我们的项目添加一个空的Const.swift文件,在其中,我们将原本oc中不需要接受参数的宏,定义成let常量,将需要接受参数的宏定义成函数即可,由于我们的整个项目共享命名空间,我们就可以在项目内的任何地方直接使用Const.swift中定义的这些公共的常量和函数
    http://www.jianshu.com/p/5f5f7c4e1dc0

    static & class

    1,结构体struct和枚举enum的静态属性,静态方法使用static关键字
    2,类class的类型属性,类型方法使用class关键字
    http://www.hangge.com/blog/cache/detail_520.html

    相关文章

      网友评论

          本文标题:Swfit语法tips

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