【发布时间】:2016-05-29 20:03:21
【问题描述】:
我在 ObjC 方面有一些经验,而且我刚刚开始学习 Swift。在 Objc 中,一切都是通过.h 和.m 中的@interface 和@implementation 的类,或者在我见过的其他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 的比较,即不要只将其视为特定问题,将其视为一般问题并解释或链接理解此问题所需的先决条件的详细信息)
【问题讨论】:
-
MVC 和 OOP 没有共同点。您可以使用 OOP(对象、类)来实现 MVC 模式,但您不必这样做。此外,从架构的角度来看,类和结构几乎是相同的。您可以使用它们中的任何一个来实现一个对象。
-
头文件 (
*.h) 存在的原因纯粹是历史原因。使用它们是因为 40 年前的编译器需要它们,而我们现在无法将它们从语言中删除。.swift文件是.m文件,你不需要.h。 -
有这个WWDC2015 video,涉及到一些主题,也许有助于进一步理解这个主题。
标签: objective-c swift class model-view-controller