假设我有一个包含帖子的用户类:
class User {
internal var id: Int
internal var posts: Entities<Post>
}
let myUser = User()
现在我想获取属于此用户的所有帖子,例如:
myUser.posts.fetchAllForUser(myUser.id)
但是,我希望避免将myUser.id
作为fetchAllForUser
中的参数传递。如何访问由myUser.id
实施的fetchAllForUser
中的posts
?
修改
myUser.posts.fetchAllForUser(myUser.id)
的问题在于self
中的fetchAllForUser
实际上是posts
。 我需要self.self
之类的内容,但self.self
本身就是self
,大声笑; - )
此外,通用类Entities<T>
符合Fetchable
:
class Entities<Element> : Fetchable { ... }
因为我被问到 - 这是Fetchable
的预期定义是什么样的:
protocol Fetchable {
associatedtype Element
func fetchAllForUser(onSuccess: () -> [Element], onError: () -> Void) { ... }
}
请参阅,我真的不想将user.id作为参数传递
答案 0 :(得分:2)
您可以简单地制作一个包含self
EntitiesDelegate
变量的User
协议,而不是尝试使用id
来访问该用户。此解决方案在Cocoa Touch中使用称为委托的通用设计模式。
protocol EntitiesDelegate {
var id: String {get set}
}
然后,您将在EntitiesDelegate
类内部创建对Entities
的引用,并将fetchAllForUser
方法的定义更改为id
参数为零默认。如果传入id
,则可以使用它,但如果不是,请使用代理id
代替使用Nil Coalescing Operator(请注意,这可能是{ {1}}也是如此,如果两者都是nil
)
nil
然后,您只需使其符合class Entities<Element> : Fetchable {
var delegate: EntitiesDelegate?
func fetchAllForUser(id: Int = nil, onSuccess: () -> [Element], onError: () -> Void) {
guard let idToUse = id ?? delegate?.id else {
return //Maybe throw an error here
}
//Use idToUse from here on
}
}
协议即可在User
课程中实现此功能。
EntitiesDelegate
那就是它!您现在可以通过class User: EntitiesDelegate {
...
init(...) {
...
posts.delegate = self
}
}
调用该方法,因为您的myUser.posts.fetchAllForUser()
课程中已经有id
变量,您甚至不需要更改任何内容来制作它符合User
。
如果您尝试按照Swift 3设计模式进行操作,则可能需要将方法签名更改为EntitiesDelegate
,可以使用func fetchAll(for id: Int = nil...)
或myUser.posts.fetchAll()
进行调用。你想指定一个id。
答案 1 :(得分:1)
如果我理解你需要什么,这是一个可能的解决方案
首先让我们定义你的模型
struct Post {
let userID: String
}
struct User {
let id: String
let posts: [Post]
init(id: String, posts:[Post]) {
self.id = id
self.posts = posts
}
}
接下来,您需要一个从网络中检索某些数据的类(例如以JSON格式)并将该数据转换为Post
final class Dao {
static let sharedInstance = Dao()
private init() { }
func fetchUser(id:String, completion: (user: User?) -> ()) {
// call webservice
// convert NSData to JSON
// extract id and posts from JSON
// create User value
// if everything goes fine then call completion(user)
// else call comletion(nil)
}
}
我建议您使用SwiftyJson和Alamofire进行Dao实施
现在你可以写
了Dao.sharedInstance.fetchUser("1") { (user) in
if let user = user {
print(user.posts)
}
}