swift 我的函数被多次调用[已关闭]

yqkkidmi  于 2023-01-12  发布在  Swift
关注(0)|答案(1)|浏览(104)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
23小时前关门了。
Improve this question
我正在使用firebase来存储我的数据,我注意到我的读写加起来已经达到了一个过高的数字,如此之高以至于我的速率受到了限制。
我决定检查我的代码并放置print语句以弄清楚发生了什么,并注意到我的代码似乎被多次调用?
下面是我的PostService.swift(函数原点)[为便于阅读而缩短]

struct PostService {

func fetchPosts(completion: @escaping([Post]) -> Void) {
    print("posts")
    Firestore.firestore().collection("posts")
        .order(by: "timestamp", descending: true)
        .getDocuments { snapshot, _ in
            guard let documents = snapshot?.documents else { return }
            let posts = documents.compactMap({ try? $0.data(as: Post.self) })
            completion(posts)
        }
}

func fetchStories(completion: @escaping([Story]) -> Void) {
    print("stories")
    Firestore.firestore().collection("stories")
        .order(by: "timestamp", descending: true)
        .addSnapshotListener { snapshot, _ in
            guard let documents = snapshot?.documents else { return }
            let stories = documents.compactMap({ try? $0.data(as: Story.self) })
            completion(stories)
        }
}

func fetchPostStats(post: Post) {
    print("fetching post stats")
    let docRefComments = Firestore.firestore().collection("posts").document(post.id!).collection("comments")
    
    docRefComments.getDocuments { snapshot, _ in
        guard let commentCount = snapshot?.documents.count else { return }
        
            
            Firestore.firestore().collection("posts")
                .document(post.id!)
                .updateData(["comments": commentCount]) { _ in
                }
        }
        
        
    }
    
    
    func fetchRecentPosts(completion: @escaping([Post]) -> Void) {
        print("fetching recent posts")
        Firestore.firestore().collection("posts")
            .order(by: "timestamp", descending: true)
            .addSnapshotListener { snapshot, _ in
                print(snapshot?.count)
                guard let documents = snapshot?.documents else { return }
                let posts = documents.compactMap({ try? $0.data(as: Post.self) })
                completion(posts)
            }
    }
    

    
    
}

// Like functionality
extension PostService {    
         
    func checkIfUserLikedPost(_ post: Post, completion: @escaping(Bool) -> Void) {
        print("checking if user liked post")
        guard let uid = Auth.auth().currentUser?.uid else { return }
        guard let postId = post.id else { return }
        
        Firestore.firestore().collection("users")
            .document(uid)
            .collection("user-likes")
            .document(postId).addSnapshotListener { snapshot, _ in
                guard let snapshot = snapshot else { return }
                completion(snapshot.exists)
            }
}

如上所示,我在每个函数下都放置了print语句。
在控制台中,我将这些print语句中的每一条都发送多次

下面是我唯一的代码获取职位和故事,这应该是问题的权利?:

class FeedViewModel: ObservableObject {
    @Published var posts = [Post]()
    @Published var stories = [Story]()

    let service = PostService()
    let userService = UserService()
    
    init() {
        fetchPosts()
        fetchStories()
    }
    
    func fetchPosts() {
        service.fetchPosts { posts in
            self.posts = posts
            
            for i in 0 ..< posts.count {
                let uid = posts[i].uid
                
                self.userService.fetchUser(withUid: uid) { user in
                    self.posts[i].user = user
                    
                }
            }
        }
    }
        
    func fetchStories() {
        service.fetchStories { stories in
            self.stories = stories
            
            for i in 0 ..< stories.count {
                let uid = stories[i].uid
                
                self.userService.fetchUser(withUid: uid) { user in
                    self.stories[i].user = user
                    
                }
            }
        }
    }
    }

查看代码:

struct FeedView: View {
    @StateObject var viewModel = FeedViewModel()
    @EnvironmentObject var authViewModel: AuthViewModel
    @Environment(\.colorScheme) var colorScheme
    @State private var showingPopover = false
    @State var showAlert = false
    @State private var showMenu = false
    @State private var showNewPostView = false
    @State var navigateTo: AnyView?
    @State var isActive = false
    

    
    var body: some View {
}

非常感谢帮助,因为这给我的申请带来了很多困难:)

tktrz96b

tktrz96b1#

视图模型初始化的任何时候,模型都会获取你的帖子。视图被SwiftUI刷新的任何时候,init()都会被调用。所以必须有刷新你的视图的东西反复调用它。
我可以建议把fetch调用移到视图层次结构中较高的.onAppear中吗?这应该只根据视图层次结构触发fetch * 一次 *。如果你有某种根视图,那么它应该只在OS会话建立时触发一次。
如果ObservableObject在视图层次结构中传递(没有StateObject),这个函数也会被调用一堆,因为SwiftUI不会保留那个类,也不会根据需要重新初始化它。这就是为什么我建议从视图中触发这个函数。
如果你能在你的问题中包含你的视图代码,那么我们可能会给予你一个更符合上下文的答案。
编程愉快。

相关问题