1.给UICollectionView或者UITableView扩展分类,提供注册cell或者注册header\footer,获取重复利用的cell

public extension UICollectionView {
    
    // MARK: - Cell register and reuse
    /**
     Register cell nib
     
     - parameter aClass: class
     */
    func ts_registerCellNib<T: UICollectionViewCell>(_ aClass: T.Type) {
        let name = String(describing: aClass)
        let nib = UINib(nibName: name, bundle: nil)
        self.register(nib, forCellWithReuseIdentifier: name)
    }
    
    /**
     Register cell class
     
     - parameter aClass: class
     */
    func ts_registerCellClass<T: UICollectionViewCell>(_ aClass: T.Type) {
        let name = String(describing: aClass)
        self.register(aClass, forCellWithReuseIdentifier: name)
    }
    
    /**
     Dequeue reusable cell
     
     - parameter aClass:    class
     - parameter indexPath: indexPath
     
     - returns: cell
     */
    func ts_dequeueReusableCell<T: UICollectionViewCell>(_ aClass: T.Type, forIndexPath indexPath: IndexPath) -> T! {
        let name = String(describing: aClass)
        guard let cell = dequeueReusableCell(withReuseIdentifier: name, for: indexPath) as? T else {
            fatalError("\(name) is not registed")
        }
        return cell
    }
    
    // MARK: - Header register and reuse
    /**
     Register header nib
     
     - parameter aClass: class
     */
    func ts_registerHeaderNib<T: UICollectionReusableView>(_ aClass: T.Type) {
        let name = String(describing: aClass)
        let nib = UINib(nibName: name, bundle: nil)
        self.register(nib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: name)
    }
    
    /**
     Register header nib
     
     - parameter aClass: class
     */
    func ts_registerHeaderClass<T: UICollectionReusableView>(_ aClass: T.Type) {
        let name = String(describing: aClass)
        self.register(aClass, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: name)
    }
    
    /**
     Dequeue reusable header
     
     - parameter aClass:    class
     - parameter indexPath: indexPath
     
     - returns: cell
     */
    func ts_dequeueReusableHeader<T: UICollectionReusableView>(_ aClass: T.Type, forIndexPath indexPath: IndexPath) -> T! {
        let name = String(describing: aClass)
        guard let view = dequeueReusableSupplementaryView(
            ofKind: UICollectionElementKindSectionHeader,
            withReuseIdentifier: name,
            for: indexPath) as? T else {
                fatalError("\(name) is not registed")
        }
        return view
    }
    
    // MARK: - Footer register and reuse
    /**
     Register header nib
     
     - parameter aClass: class
     */
    func ts_registerFooterNib<T: UICollectionReusableView>(_ aClass: T.Type) {
        let name = String(describing: aClass)
        let nib = UINib(nibName: name, bundle: nil)
        self.register(nib, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: name)
    }
    
    /**
     Register header nib
     
     - parameter aClass: class
     */
    func ts_registerFooterClass<T: UICollectionReusableView>(_ aClass: T.Type) {
        let name = String(describing: aClass)
        self.register(aClass, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: name)
    }
    
    /**
     Dequeue reusable header
     
     - parameter aClass:    class
     - parameter indexPath: indexPath
     
     - returns: cell
     */
    func ts_dequeueReusableFooter<T: UICollectionReusableView>(_ aClass: T.Type, forIndexPath indexPath: IndexPath) -> T! {
        let name = String(describing: aClass)
        guard let view = dequeueReusableSupplementaryView(
            ofKind: UICollectionElementKindSectionFooter,
            withReuseIdentifier: name,
            for: indexPath) as? T else {
                fatalError("\(name) is not registed")
        }
        return view
    }
}

2.给UIView扩展,添加加载nib文件类方法

 /**
 Init from nib and get the view
 Notice: The nib file name is the same as the calss name
 
 Demo: UIView.ts_viewFromNib(TSCustomView)
 
 - parameter aClass: your class
 
 - returns: Your class's view
 */
class func ts_viewFromNib<T>(_ aClass: T.Type) -> T {
    let name = String(describing: aClass)
    if Bundle.main.path(forResource: name, ofType: "nib") != nil {
        return UINib(nibName: name, bundle:nil).instantiate(withOwner: nil, options: nil)[0] as! T
    } else {
        fatalError("\(String(describing: aClass)) nib is not exist")
    }
}

3.泛型函数的应用

3.1应用需求:定义一个函数,传一个泛型数组,要求每10个item分成一组,返回一个泛型二维数组

/// Creates an array of elements split into groups the length of size.
/// If array can’t be split evenly, the final chunk will be the remaining elements.
///
/// - parameter array: to chunk
/// - parameter size: size of each chunk
/// - returns: array elements chunked
open class func chunk<T>(_ array: [T], size: Int = 10) -> [[T]] {
    var result = [[T]]()
    var chunk = -1
    for (index, elem) in array.enumerated() {
        if index % size == 0 {
            result.append([T]())
            chunk += 1
        }
        result[chunk].append(elem)
    }
    return result
}

3.2获取数组中某个元素的索引

class func find <T: Equatable> (array: [T], item : T) ->Int? {
   var index : Int = 0
        while(index < array.count) {
            if(item == array[index]) {
                return index
            }
            index = index+1
        }
    return nil
}

3.3合并两个字典

/**
 Combine the two dictionary
 
 - parameter left:  The left dictionary
 - parameter right: The right dictionary
 
 - returns: The new dictionary.
 */
func ts_combine<K, V>(_ left: Dictionary<K, V>, right: Dictionary<K, V>) -> Dictionary<K, V> {
    var map = Dictionary<K, V>()
    for (k, v) in left {
        map[k] = v
    }
    for (k, v) in right {
        map[k] = v
    }
    return map
}

4.系统min函数,求两个或者多个相同类型元素的最小值

//  T 需要满 足 Comparable
func min<T: Comparable>(_ x: T, _ y: T) -> T {
    return y < x ? y : x
}

Swift4归档解档,对存储的数据进行泛型约束

public func setObject<T: Codable>(_ object: T,forKey key:String) {
    cacheQueue.async { [weak self] in
        //dispatch asynchronously on cacheQueue
        guard let path = self?.pathForKey(key) else{
            print("File at path for key : \(key) not found")
            return
        }
        do{
            let data = try PropertyListEncoder().encode(object)
            let success = NSKeyedArchiver.archiveRootObject(data, toFile: path)
            var fileUrl = URL.init(fileURLWithPath: path)
            self?.excludeFromBackup(fileUrl: &fileUrl)
            print(success ? "data saved to cache SUCCESSFULLY" : "data caching FAILED")
        }catch{
            print("data caching FAILED")
        }
    }
}

Generics(泛型)-Apple官方文档

Source: TimedSilver