我在 ObjC 方面有一些经验,而且我刚刚开始学习 Swift。在 Objc 中,一切都是通过 @interface
的类在 .h
和 @implementation
的 .m
,或者在我见过的其他 Swift 类中,一切通常都是某种形式的
class MyCustomClassInhertingfrom: SomeFoundationClass { //methods & properties}
然而在一些名为 pancakeHouse.Swift
的类中没有提到关键字 class
为什么?这不是模型类吗?这不是破坏了MVC设计模式吗?发生这种情况是因为 Swift 中枚举和结构与类的新强大功能吗?_____我显然很困惑!
import UIKit
import CoreLocation
enum PriceGuide : Int {
case Unknown = 0
case Low = 1
case Medium = 2
case High = 3
}
extension PriceGuide : CustomStringConvertible {
var description : String {
switch self {
case .Unknown:
return "?"
case .Low:
return "$"
case .Medium:
return "$$"
case .High:
return "$$$"
}
}
}
enum PancakeRating {
case Unknown
case Rating(Int)
}
extension PancakeRating {
init?(value: Int) {
if value > 0 && value <= 5 {
self = .Rating(value)
} else {
self = .Unknown
}
}
}
extension PancakeRating {
var ratingImage : UIImage? {
guard let baseName = ratingImageName else {
return nil
}
return UIImage(named: baseName)
}
var smallRatingImage : UIImage? {
guard let baseName = ratingImageName else {
return nil
}
return UIImage(named: "\(baseName)_small")
}
private var ratingImageName : String? {
switch self {
case .Unknown:
return nil
case .Rating(let value):
return "pancake_rate_\(value)"
}
}
}
struct PancakeHouse {
let name: String
let photo: UIImage?
let thumbnail: UIImage?
let priceGuide: PriceGuide
let location: CLLocationCoordinate2D?
let details: String
let rating: PancakeRating
}
extension PancakeHouse {
init?(dict: [String : AnyObject]) {
guard let name = dict["name"] as? String,
let priceGuideRaw = dict["priceGuide"] as? Int,
let priceGuide = PriceGuide(rawValue: priceGuideRaw),
let details = dict["details"] as? String,
let ratingRaw = dict["rating"] as? Int,
let rating = PancakeRating(value: ratingRaw) else {
return nil
}
self.name = name
self.priceGuide = priceGuide
self.details = details
self.rating = rating
if let imageName = dict["imageName"] as? String where !imageName.isEmpty {
photo = UIImage(named: imageName)
} else {
photo = nil
}
if let thumbnailName = dict["thumbnailName"] as? String where !thumbnailName.isEmpty {
thumbnail = UIImage(named: thumbnailName)
} else {
thumbnail = nil
}
if let latitude = dict["latitude"] as? Double,
let longitude = dict["longitude"] as? Double {
location = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
} else {
location = nil
}
}
}
extension PancakeHouse {
static func loadDefaultPancakeHouses() -> [PancakeHouse]? {
return self.loadPancakeHousesFromPlistNamed("pancake_houses")
}
static func loadPancakeHousesFromPlistNamed(plistName: String) -> [PancakeHouse]? {
guard let path = NSBundle.mainBundle().pathForResource(plistName, ofType: "plist"),
let array = NSArray(contentsOfFile: path) as? [[String : AnyObject]] else {
return nil
}
return array.map { PancakeHouse(dict: $0) }
.filter { $0 != nil }
.map { $0! }
}
}
extension PancakeHouse : CustomStringConvertible {
var description : String {
return "\(name) :: \(details)"
}
}
extension PancakeHouse: Equatable {
}
func ==(lhs: PancakeHouse, rhs: PancakeHouse) -> Bool {
return lhs.name == rhs.name
}
注意: 如果您的回答还包括对 .swift
的比较,我将不胜感激。对比.h
+ .m
即不要只将其视为一个特定问题,将其视为一个一般问题,并解释或链接理解该问题所需的先决条件的详细信息)
最佳答案
pancakeHouse.swift
定义了 PancakeHouse
以及所有与之相关的东西。这是非常好的 Swift 风格。这里没有 class
,因为 PancakeHouse
恰好是一个 struct
,这也是非常好的 Swift 风格(并且稍微偏爱)。结构很像 Swift 中的类,因为它们可以有数据和方法(和扩展)。
ObjC 不要求每个类都在其自己的 .h/.m 对中定义,但这样做是相当典型的 ObjC 风格。也就是说,即使在 ObjC 中也有异常(exception)。将可变子类定义在与其基类相同的文件中是很常见的(NSArray
和 NSMutableArray
都在 NSArray.h
中定义)。 Swift 风格已经朝着将相关事物更紧密地集中在一起的方向发展。如果您知道某个样式的名称,则一种样式可以更轻松地找到它。另一个使一起查找相关概念变得更加容易。两者各有优势,一旦人们习惯了其中一种,他们就会倾向于认为那一种显然是正确的。但它们只是不同的组织方式。
请注意,此文件还使用 Swift 扩展来分解相关方法。这也是常见且好的 Swift。旧的 ObjC 使用类别来做到这一点,但如今以这种方式组织 ObjC 代码的情况要少得多(类别现在用于其他用途)。同样,两者都不是完全正确的。只是风格发生了变化。
关于objective-c - 每个 .swift 文件不应该是一个类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37514386/