@FetchRequest inits an object DeferredFetchRequest every time which seems like a mistake

Originator:indiekiduk
Number:rdar://FB9956812 Date Originated:14/3/22
Status:Open Resolved:No
Product:SwiftUI Product Version:Xcode 13.3
Classification:Bug Reproducible:Always
 
In SwiftUI we are supposed to be careful not to init objects however I noticed that every time a View containing @FetchRequest the body is always called, regardless if there are any changes or not. In digging deeper I noticed that the FetchRequest struct contains an object DeferredFetchRequest which is alloc init every time the FetchRequest is init, this looks like a mistake to me so thought I would report it. DynamicProperties like FetchRequest can use @StateObject for objects, like it is doing for the controller object. Below is a dump of a fetchRequest, the object in question is shown last.

Printing description of self.fetchRequest:
▿ FetchRequest<Item>
  ▿ _managedObjectContext : Environment<NSManagedObjectContext>
    ▿ content : Content
      - value : <NSManagedObjectContext: 0x600001838750>
  ▿ _controller : StateObject<FetchController<(), Item, FetchedResults<Item>>>
    ▿ storage : Storage
      ▿ object : ObservedObject<FetchController<(), Item, FetchedResults<Item>>>
        - _seed : 1
        ▿ wrappedValue : <_TtGC7SwiftUI15FetchControllerT_C16DynamicFetchTest4ItemGVS_14FetchedResultsS2___: 0x6000007384e0>
  ▿ _results : State<Optional<FetchedResults<Item>>>
    - _value : nil
    ▿ _location : Optional<AnyLocation<Optional<FetchedResults<Item>>>>
      ▿ some : <StoredLocation<Optional<FetchedResults<Item>>>: 0x600002d41200>
  ▿ transaction : Transaction
    ▿ plist : [Key<AnimationKey> = Optional(AnyAnimator(SwiftUI.BezierAnimation(duration: 0.35, curve: SwiftUI.(unknown context at $1ba496d1c).BezierTimingCurve(ax: 0.52, bx: -0.78, cx: 1.26, ay: -2.0, by: 3.0, cy: 0.0))))]
      ▿ elements : Optional<Element>
        ▿ some : Key<AnimationKey> = Optional(AnyAnimator(SwiftUI.BezierAnimation(duration: 0.35, curve: SwiftUI.(unknown context at $1ba496d1c).BezierTimingCurve(ax: 0.52, bx: -0.78, cx: 1.26, ay: -2.0, by: 3.0, cy: 0.0))))
  ▿ deferredFetchRequest : <DeferredFetchRequest<Item>: 0x600002d71410>

I would like to be able to use FetchRequest in a View and have body only called if it is different from last time it was init, currently impossible because of this object being init inside it.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!