English 中文(简体)
页: 1 每当迅速修改观点时,即可重新加入。 UI
原标题:@Observable is being re-init every time view is modified in SwiftUI

I am surprised and don t really understand the behavior I am seeing with the new @Observable framework in iOS 17.

看来,如果对包含“国与国”的观点加以修改,那么这种观点的内涵也将被称作“摩德尔”。 这并不是使用观点的先前国家目标方法的行为。

例:

struct ContentView: View {
    
    @State var offset = false
    
    var body: some View {
        VStack {
            InnerView()
                .offset(x: offset ? 200 : 0)
                
            Button("Offset") {
                offset.toggle()
            }
        }
    }
}


// iOS 17 Observable method:

struct InnerView: View {
    
    @State var viewModel: ViewModel
    
    init() {
        self._viewModel = State(wrappedValue: ViewModel())
    }
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
        }
        .padding()
    }
}

@Observable
class ViewModel {
    
    init() {
        print("ViewModel Init")
    }
}


// StateObject method:

struct InnerView: View {
    
    @StateObject var viewModel: ViewModel
    
    init() {
        self._viewModel = StateObject(wrappedValue: ViewModel())
    }
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
        }
        .padding()
    }
}

class ViewModel: ObservableObject {
    
    init() {
        print("ViewModel Init")
    }
}

这一预期行为吗?

问题回答

是的。 这种行为是完全期望的。

SwiftUI s @State is regenerated each time the View is drawn.
In other words, it depends on the life cycle of the View.

In your code, when the Offset button is clicked, the UI inside the ContentView will change.
This means that the body of the ContentView will be completely redrawn. Therefore, the InnerView() will be regenerated each time.

At the same time, any @State variables that exist inside the InnerView will also be recreated. As mentioned, @State is dependent on the life cycle of the View it is in.

然而,@StateObject 并不取决于<代码>>的生命周期,而是取决于宣布该物体的集装箱的生命周期。

页: 1 在宣布国家物体的集装箱使用寿命期间,国际不动产公司只创立了一个模型物体的新例子。 例如,快速 如果某一观点的投入发生变化,则国际不动产业联合会没有创造新的榜样,但如果观点的特性发生变化,则会创造新的榜样。

Note:
that this is not an issue specific to iOS 17.
This is because it s not an issue with @Observable, but rather with the usage of @State.

I found a good answer in another article that is related.
What is the difference between ObservedObject and StateObject in SwiftUI

This is curious! I ve dug into it a bit, and I think I understand the reason for the discrepancy. But before that we need to understand each case a bit better.

<代码>@ 可见方法,指出初始使用人每当你在装物时被称作“,但使用(在第一次使用后)初始化器的结果。

每次被点名确实是有意义的。 T(Inner View init) 你们看到,每当内言重新构造时,便会打上 in子。

因此,关于每一重建,State(已清理) 价值:见观点/代码。

但有些魔力正在这里发生,这超出了我所能看到的能力(但我可以猜测执行情况,因此不能说是神论),因为只有使用“条码”的首例。 我深信这一点,把每个例子区别开来(利用全球和实例反):

var globalCounter = 0

// iOS 17 Observable method:

struct InnerView: View {
    @State private var viewModel: ViewModel
    
    init() {
        print("Inner View init")
        self._viewModel = State(wrappedValue: ViewModel())
    }
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
            Text("State counter is (viewModel.counter)")
            Text("Global counter is (globalCounter)")
        }
        .padding()
    }
}


@Observable
private class ViewModel {
    var counter: Int
    
    init() {
        globalCounter += 1
        counter = globalCounter
        print("ViewModel Init")
    }
}

由于我们认为,“国家反制”的标签没有更新,而全球反制变化则可以得出结论,只有首先使用。

然而,这要问: 最初的遗嘱人每次都不要求其他方法吗? 同样,你可以看到(通过添加“内部观点”的<条码>(>),如同第一种方法一样)内语初始器正在每次被称作。 因此,它看上去的是<代码>本身。 数值:每当你在<代码>上点击时,请见。 页: 1 但ViewModel () 未被点名(见观点Model初始器缺乏印刷)。 因此,如何做到这一点?

我想,这是因为@autoclosure。 迅速加入 用于确定<代码>的初始用户的建筑师 StateObject:

数值:@autoclosure @escaping (千美元) -> ObjectType:

因此,StateObject _being换算成封闭。 只是在需要的时候(即建立国家观点)。

因此,你的问题是,“这一预期行为吗?” 我认为,我已经表明存在差异之处。 是否期望? d 我说,在这种详细程度上,没有什么期望。 然而,目前实现的更重要期望是,国家实体(无论是传统国家、观察国还是国家目标)与某种特定观点有关,只是一劳永逸地形成这种观点。

In the case of @Observed, there are some extra instances being created and discarded, and there s an efficiency hit from that. But your program behaviour will probably not be unaffected.

Having said that, my preference would be that Apple updated the State initializer to also use an autoclosure in the future. (Or at least give us an alternate initializer)

Also note that if the current discrepancy is a problem for you, you might be able to build a workaround, depending on your circumstances, and if my above inferences are correct.

我希望能帮助!





相关问题
SwiftUI: How do I position a button x points above a sheet?

I am trying to recreate a Maps-style UI with a persistent bottom sheet and controls fixed above. Apple Maps UI with controls above ☝️ Example here, the "Look Around" binoculars button and ...

BraintreeDropIn deprecated functions error

I m getting this error on the latest release of BraintreeDropIn, I really don t get it since based on the patch notes, this should ve been addressed already, I have already tried cleaning derived data,...

how to limit zoom level in map swift ui?

how to limit zoom level in map swift ui i have map and need to make zoom level limited Map(coordinateRegion: $region,annotationItems: viewModel.nearbyGyms) { item in ...

UIImageView - How to get the file name of the image assigned?

Is it possible to read the name of an UIImageView s UIImage that s presently stored in the UIImageView? I was hoping you could do something kind of like this, but haven t figured it out. NSString *...