Swiftui视图关闭后如何清理环境对象?

时间:2020-01-04 17:37:15

标签: swift swiftui deinit

我有一个相当大的项目,我从情节提要和xibs开始。现在,我正在使用swiftui实现一些新视图。这是我用来执行此操作的代码:

func goToSchedule() {
    let scheduleController = ScheduleController()
    let vc = UIHostingController(rootView: ScheduleView().environmentObject(scheduleController))
    if let topController = UIApplication.topViewController() {
        topController.present(vc, animated: true, completion: nil)
    }
}

但是当我关闭(向下滑动)视图并再次打开它时,我遇到了一个问题,每次执行此操作都会创建环境对象的额外副本,该对象是一个处理tcp连接的类,即缩短的代码如下:

class ScheduleController: ObservableObject, NetworkDelegate {
    var didChange = PassthroughSubject<Void, Never>()
    @Published var timers = [ScheduleTimer]()
    let connection = tcpNetwork()
    init() {
        connection.delegate = self
    }
    func send(data: String) {
        self.connection.sendMsg(data)
    }
    func processData(data: String) {
    // long function where the received data is parsed and the timers array is updated
}}

视图是这样的:

struct ScheduleView: View {
@EnvironmentObject var scheduleController: ScheduleController

var body: some View {
    NavigationView {
      List {
        ForEach(scheduleController.timers, id: \.self) { timer in
            TimerRow(id: timer.id, name: timer.name, startTimer: timer.start, endTimer: timer.end, isActive: timer.isActive)
        }
      }}

1 个答案:

答案 0 :(得分:0)

只需用ObservedObject替换EnvironmentObject并将其添加到ScheduleController的deinit方法即可解决此问题

#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <stdio.h>
#include <X11/extensions/XTest.h>

int main (int argc, char* * argv) {
    Display * dpy;

    dpy = XOpenDisplay(NULL);   
                XDevice *pointer1;
                XDevice *pointer2;
                XEvent ev;
                int type_bpress;
                XEventClass cls[1];
                pointer1 = XOpenDevice(dpy, 12); /* get the ID from ListInputDevices */

                /* register for events */
                DeviceButtonPress(pointer1, type_bpress, cls[0]);
                XSelectExtensionEvent(dpy, RootWindow(dpy, DefaultScreen(dpy)), cls, 2);

                while(1) {
                XNextEvent(dpy, &ev);
                printf("Event type %d received\n", ev.type);
                if (ev.type == type_bpress)
                {
                        XDeviceButtonEvent* bev = (XDeviceButtonEvent*)&ev;
                        printf("Press received by device %d\n", bev->deviceid);
                }
                }

    XCloseDisplay(dpy);
    return 0;
}