Post

Replies

Boosts

Views

Activity

Data update issue when both parent and child views are @State in SwiftUI
Here is my test code import SwiftUI struct SubView1: View { @State var data: String var body: some View { Text(data) let _ = addr() } func addr() { let a = withUnsafePointer(to: data) { pointer in return"\(pointer)" } let b = withUnsafePointer(to: self) { pointer in return"\(pointer)" } print("SubView1, \(a), \(b), \(self)") } } struct SubView2: View { var data: String var body: some View { Text(data) let _ = addr() } func addr() { let a = withUnsafePointer(to: data) { pointer in return"\(pointer)" } let b = withUnsafePointer(to: self) { pointer in return"\(pointer)" } print("SubView2, \(a), \(b), \(self)") } } struct ContentView: View { @State var data: String = "a" var body: some View { let _ = print("ContentView") SubView1(data: data) SubView2(data: data) Button("change") { data = "b" print("changed") } } } Here is what is printed ContentView SubView1, 0x000000016ce791a8, 0x000000016ce79170, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView1, 0x000000016ce79260, 0x000000016ce79230, SubView2(data: "a") changed ContentView SubView1, 0x000000016ce7d548, 0x000000016ce7d510, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView1, 0x000000016ce7d600, 0x000000016ce7d5d0, SubView2(data: "b") In my understanding, @State wrapping is monitoring of variables, and when the wrapped variables change, it will trigger the update of this page. Updating the interface means recreating the body, so all subpages will be recreated. When I click the button, the data of ContentView is updated first, which leads to the update of ContentView , and then leads to the reconstruction of SubView1 and SubView2. Judging from the changed address, it is indeed rebuilt rather than reused. But the problem is that the data of ContentView has been updated to "b" at this time, and SubView2 is indeed reinitialized using "b", so why does SubView1 still use "a"? In addition, I modified another one and added a SubView1 to ContentView struct ContentView: View { @State var data: String = "a" var body: some View { let _ = print("ContentView") SubView1(data: data) SubView2(data: data) SubView1(data: data) Button("change") { data = "b" print("changed") } } } The following result was obtained ContentView SubView1, 0x000000016d9cd1a8, 0x000000016d9cd170, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView2, 0x000000016d9cd260, 0x000000016d9cd230, SubView2(data: "a") SubView1, 0x000000016d9cd1a8, 0x000000016d9cd170, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) changed ContentView SubView1, 0x000000016d9d1548, 0x000000016d9d1510, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView2, 0x000000016d9d1600, 0x000000016d9d15d0, SubView2(data: "b") SubView1, 0x000000016d9d1548, 0x000000016d9d1510, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) It seems that the two SubView1 are the same object?
2
0
384
Jun ’24
SwiftUI UI auto refresh problem
import SwiftUI class MyData: ObservableObject { var id: String = "" @Published var count: Int = 0 init(id: String) { self.id = id } } struct ContentView: View { @State var list: [MyData] = [MyData(id: "sub a"), MyData(id: "sub b")] @State var count: Int = 0 var body: some View { VStack(spacing: 0) { Button("click \(count)") { count += 1 // call from here has no problem // setAllType(on: count) } Divider() ForEach(list, id: \.id) { type in Text("\(type.id): \(type.count)") } } .onChange(of: count) { // call from here has problem setAllType(on: count) } .frame(width: 100, height: 100) } func setAllType(on: Int) { for type in list { type.count = on } } } Let me briefly explain my code. I have a class called MyData, which has a @Published var count: Int. At the same time, in the view, I have a @State var list: [MyData] array, and a @State var count: Int. When I click the button, I increment count, and call setAllType to set the count for all MyData instances in the list. Now the problem arises with the setAllType function. If I call it in the Button's click event, everything works as expected. However, if I use onChange to monitor the changes of count, and then call setAllType, there's an issue. The specific problem is that the count displayed by ForEach for MyData is always one less than the count displayed by the Button. They should be equal.
2
0
601
Mar ’24
There seems to be some issues with Network Extension.
hi I have a Network Extension that uses content-filter-provider-systemextension. It has been running stably before, but some problems occurred after I updated the system to MacOS 14.1. The main problem is that I registered the data filtering of the loopback address of 127, which caused a direct error in my DataGrip software, even if I directly returned .allow() in the handler function example code: class Filter: NEFilterDataProvider { // MARK: NEFilterDataProvider override func startFilter(completionHandler: @escaping (Error?) -> Void) { // loop, all 127.*.*.* will matched let loNetworkRules4 = NENetworkRule( remoteNetwork: NWHostEndpoint(hostname: "127.0.0.1", port: "0"), remotePrefix: 0, localNetwork: NWHostEndpoint(hostname: "127.0.0.1", port: "0"), localPrefix: 0, protocol: .any, direction: .any ) let loFilterRule4 = NEFilterRule(networkRule: loNetworkRules4, action: .filterData) let filterSettings = NEFilterSettings(rules: [loFilterRule4], defaultAction: .filterData) apply(filterSettings) { error in if let applyError = error { } completionHandler(error) } } override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict { return .allow() } } This will cause DataGrip's database connection test to report an error directly. It seems that the local network communication of Java is blocked. So I also used nc to test the local network. nc -l 8888 nc 127.0.0.1 8888 But the result obtained is completely fine Everything got better when I rolled the system back to macos14 Now I have updated the system to macos14.2 and the problem remains I've submitted feedback on this issue in Feedback Assistant FB13463323 But obviously the feedback is too slow, I can't wait a bit, so I took the liberty to send you an email to ask for help I want to confirm if this is a macos bug or do I need to modify some NENetworkRule configurations? If it is confirmed to be a BUG, how long will the repair cycle take? If it will be fixed soon, then I will just wait for the system to be repaired. If the repair cycle will be very long, then I have to consider other solutions for my product. thanks
1
0
363
Dec ’23
The issue of toolbar item size when windowToolbarStyle is unifiedCompact
I created a window using NavigationSplitView, and also set WindowGroup{}.windowToolbarStyle(.unifiedCompact). I found that the toolbar items became smaller. In comparison, Xcode's toolbar also has a narrower vertical height, but the items maintain their original size. How is this achieved? import SwiftUI @main struct ThreeSideViewerApp: App { var body: some Scene { WindowGroup { ContentView() } .windowToolbarStyle(.unifiedCompact) } } struct ContentView: View { @State var show: Bool = true var body: some View { NavigationSplitView { Text("SideBar") } detail: { Text("detail") } } }
1
0
1.4k
Oct ’23
The problem of @State optional objects not being released in a LazyVStack
I have a LazyVStack wrapped in a ScrollView, and within the LazyVStack, there is a group of SomeThingView used to display certain things. import SwiftUI var appearCount = 0 class MyObject { static var count = 0 init(){ MyObject.count += 1 } deinit { MyObject.count -= 1 print("deinit ImageCount: \(MyObject.count)") } } struct SomeThingView: View { @State var object: MyObject? = nil @State var show: Bool = false var body: some View { ZStack { if show { // <- The issue lies here, with this condition, the image will never be released. Text("load") } else { Text("not load") } } .frame(height: 100) .onAppear { show = true object = MyObject() appearCount += 1 print("appear \(appearCount)") } .onDisappear { show = false object = nil // <- Unreferencing the image here, the image should be released. appearCount -= 1 print("disappear \(appearCount)") print("disappear ImageCount: \(MyObject.count)") } } } struct ContentView: View { var body: some View { VStack { ScrollView{ LazyVStack{ ForEach(0..<100) {_ in SomeThingView() } } } } .padding() } } The current issue lies in the fact that the @State var object: MyObject? = nil within SomeThingView is not being released due to the presence of @State var show: Bool = false. As seen above, i set show = true and object = MyObject() in the onAppear block, and in onDisappear, set show = false and object = nil. Even though i am not using object in the view, the presence of the show condition within the ZStack{} is preventing the object from being released properly. some log disappear 7 disappear ImageCount: 57 init ImageCount: 58 appear 8 disappear 7 disappear ImageCount: 58 init ImageCount: 59 appear 8 disappear 7 disappear ImageCount: 59 init ImageCount: 60 appear 8 disappear 7 disappear ImageCount: 60 init ImageCount: 61 appear 8 However, if I comment out the condition for show within the ZStack, or if I comment out the settings for show in onAppear and onDisappear, everything runs smoothly. struct SomeThingView: View { @State var object: MyObject? = nil @State var show: Bool = false var body: some View { ZStack { // if show { // <- The issue lies here, with this condition, the image will never be released. // Text("load") // } else { // Text("not load") // } } .frame(height: 100) .onAppear { show = true object = MyObject() appearCount += 1 print("appear \(appearCount)") } .onDisappear { show = false object = nil // <- Unreferencing the image here, the image should be released. appearCount -= 1 print("disappear \(appearCount)") print("disappear ImageCount: \(MyObject.count)") } } } deinit ImageCount: 9 deinit ImageCount: 8 disappear 7 disappear ImageCount: 8 init ImageCount: 9 appear 8 deinit ImageCount: 8 disappear 7 disappear ImageCount: 8 init ImageCount: 9 appear 8 deinit ImageCount: 8 disappear 7 disappear ImageCount: 8 init ImageCount: 9 appear 8 deinit ImageCount: 8 init ImageCount: 9 appear 9 disappear 8 disappear ImageCount: 9 init ImageCount: 10 appear 9 deinit ImageCount: 9 disappear 8 disappear ImageCount: 9 init ImageCount: 10 appear 9 deinit ImageCount: 9
0
0
401
Oct ’23
SystemExtension: Network Extension entitlements
According to the description of this answer - https://developer.apple.com/forums/thread/134202#reply-to-this-question I have been able to successfully load the Debug version. But when I try to use the Developer ID to sign my NetworkExtension , I met a problem, so i manual add "-systemextension" suffix (content-filter-provider-systemextension) in a new entitlements file for Release. but when i trying to install it ,i get this error message Error Domain = OSSystemExtensionErrorDomain Code = 9 "(null)" . And I get the same error when I try to retest the Debug version. so, can anybody give me some suggestion, thinks! csrutil status System Integrity Protection status: unknown (Custom Configuration). Configuration: Apple Internal: disabled Kext Signing: disabled Filesystem Protections: disabled Debugging Restrictions: disabled DTrace Restrictions: disabled NVRAM Protections: disabled BaseSystem Verification: enabled systemextensionsctl developer off spctl -a -t open --context context:primary-signature -v &(appname) &(appname): accepted source=Notarized Developer ID
2
0
1k
Nov ’20