小编Kev*_*inP的帖子

SwiftUI - 返回时如何取消初始化 StateObject?

我希望@StateObject在返回后尽快取消初始化,但该对象似乎保存在内存中。“Deint ViewModel”没有打印在返回导航上,它是在我再次导航到我来自的视图后第一次打印的。有没有办法释放@StateObject后退导航的内存?

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: TestView(), label: { Text("Show Test View") })
        }
    }
}

struct TestView: View {
    
    @StateObject private var viewModel = ViewModel()
    
    var body: some View {
        Text("Test View")
    }
}

final class ViewModel: ObservableObject {
    deinit {
        print("Deint ViewModel")
    }
}
Run Code Online (Sandbox Code Playgroud)

navigation swift swiftui

11
推荐指数
1
解决办法
3460
查看次数

不支持的架构 - Metal 和 Swift 之间的共享枚举

我尝试在 Metal 和我的 swift 项目之间共享我在头文件中定义的枚举:

#ifndef SharedIndizes_h
#define SharedIndizes_h
#import <Foundation/Foundation.h>

#endif /* SharedIndizes_h */

typedef NS_ENUM(NSInteger, VertexAttribute)
{
    VertexAttributePosition = 0,
    VertexAttributeNormal  = 1,
};
Run Code Online (Sandbox Code Playgroud)
#include <metal_stdlib>
#import "ExchangeTypes/SharedIndizes.h"
using namespace metal;

struct VertexIn {
    float3 position [[ attribute(VertexAttributePosition) ]];
    float3 normal [[ attribute(VertexAttributeNormal) ]];
};
Run Code Online (Sandbox Code Playgroud)
vertexDescriptor.attributes[VertexAttribute.position.rawValue]
vertexDescriptor.attributes[VertexAttribute.normal.rawValue]
Run Code Online (Sandbox Code Playgroud)

但我得到的只是一些意想不到的错误:

  • 不支持的架构

  • 未知类型名称“_int64_t”

  • 未知类型名称“_int32_t”

  • ...

从我的金属文件中删除#import "ExchangeTypes/SharedIndizes.h"也会消除错误。

swift metal

5
推荐指数
1
解决办法
438
查看次数

SwiftUI 将位置设置为不同视图的中心

我有两个不同的视图,一个红色矩形和一个总是位于屏幕底部的黑色矩形。当我单击红色矩形时,它应该将自身定位在另一个矩形内。

点击我

目前,红色矩形是静态定位的:.position(x: self.tap ? 210 : 50, y: self.tap ? 777 : 50)。有没有办法动态替换 210 和 777 到黑色矩形中心位置的位置?

我知道我可以使用 GeometryReader 来获取视图大小,但是如何使用该大小来定位不同的视图?这甚至是正确的方法吗?

struct ContentView: View {

    @State private var tap = false

    var body: some View {
        ZStack {
            VStack {
                Spacer()
                RoundedRectangle(cornerRadius: 10)
                    .frame(maxWidth: .infinity, maxHeight: 50, alignment: .center)
            }
            .padding()

            VStack {
                ZStack {
                    Rectangle()
                        .foregroundColor(.red)
                    Text("Click me")
                        .fontWeight(.light)
                        .foregroundColor(.white)
                }
                .frame(width: 50, height: 50)
                .position(x: self.tap ? 210 : 50, y: self.tap ? 777 : 50)
                .onTapGesture …
Run Code Online (Sandbox Code Playgroud)

swift swiftui

5
推荐指数
2
解决办法
2806
查看次数

Swift Combine - CFString(存储)内存泄漏

在 xcode 中使用内存图调试器时,我看到了一些内存泄漏。Backtrace 没有直接链接到我的任何代码,而是通过跟踪猜测它的保存以假设它与组合和一些 DataTaskPublisher 相关。

在此处输入图片说明

接下来我检查了 Instruments 内部,在那里我也看到了一些内存泄漏。所有泄漏都在堆栈跟踪中提到“专门的静态 UIApplicationDelegate.main()”,但它并没有真正链接到可能导致内存泄漏的东西。

在此处输入图片说明

删除负责从 API 加载数据的 ViewModel 可以消除泄漏。内存图调试器显示了一个 dataTaskPublisher,所以这有点道理。

import Foundation
import Combine

enum API {
    static func games() -> AnyPublisher<[GameResult], Error> {
        let requestHeaderGames = gamesRequest()
        
        return URLSession.shared.dataTaskPublisher(for: requestHeaderGames)
            .map(\.data)
            .decode(type: [GameResult].self, decoder: JSONDecoder())
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
    }
    
    private static func gamesRequest() -> URLRequest {
        let url = URL(string: "http://localhost:8080/api/games")!
        var requestHeader = URLRequest.init(url: url)
        requestHeader.httpBody =
            "filter ..."
            .data(using: .utf8, allowLossyConversion: false)

        requestHeader.httpMethod = "POST"
        requestHeader.setValue("application/json", forHTTPHeaderField: "Accept")

        return requestHeader
    } …
Run Code Online (Sandbox Code Playgroud)

memory-leaks swift swiftui combine

5
推荐指数
1
解决办法
344
查看次数

SwiftUI - 我可以为通用视图定义一个空的初始值设定项吗?

我有一个带有可选的通用视图@ViewBuilder。我想要两个初始值设定项,一个负责设置@ViewBuilder,另一个应作为空的默认值。

struct OptionalViewBuilder<Content: View>: View {
    
    let content: (() -> Content)?
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }
    
    init() {
        self.content = nil
    }
    
    var body: some View {
        VStack {
            Text("Headline")
            Divider()
            content?()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用 ViewBuilder 参数初始化视图,它当然可以工作。但是,当我使用空的初始化程序时,我收到错误消息:

无法推断通用参数“内容”

struct ContentView: View {
    var body: some View {
        OptionalViewBuilder {
            Text("Text1")
            Text("Text2")
        }
        OptionalViewBuilder() // <-- Generic parameter 'Content' could not be inferred
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道 Swift 在运行时需要显式类型,但是有没有办法让默认的初始化器工作呢?

generics swift swiftui

5
推荐指数
1
解决办法
1733
查看次数

标签 统计

swift ×5

swiftui ×4

combine ×1

generics ×1

memory-leaks ×1

metal ×1

navigation ×1