0

I have 2 ViewControllers, the first one has an array that is filled by a fetch request once the ViewController appears. The second ViewController has a reference to that array. However, that is referencing an empty array which before it's being filled.
I want to get a reference once the array is filled. Here is a snippet.

class VC1: UIViewController {
    let coreDataObjects = [NSManagedObject]() //At this moment, this array is empty
    func viewWillAppear {
        fetchRequestThatFillsTheArray() //Here, the array is filled
    }
    fetchRequestThatFillsTheArray() {
        //calling NSFetchRequest
    }
}

class VC2: UIViewController {
    let vc1 = VC1()
    vc1.coreDataObjects //Empty array
}

Thanks.

Ennabah
  • 2,303
  • 2
  • 20
  • 39
  • Do you know the difference between viewDidLoad and viewWillAppear? And what is fetchRequestThatFillsTheArray? – El Tomato Mar 18 '17 at 00:56
  • @ElTomato I've edited to code snippet to be more clear, however, fetchRequestThatFillsTheArray() is a fetch request that assigns the result of the request to the array. And yes I know the difference, also, -_just to check_-,tried calling the fetchRequestThatFillsTheArray() in viewDidLoad(), viewWillAppear() and viewDidAppear() – Ennabah Mar 18 '17 at 01:48
  • Actually, I don't think anyone can answer your question without making wild assumptions. You don't tell the relationship between VC1 and VC2. We don't know whether they reside in the same storyboard. We don't even know whether or not you use the storyboard in the first place. We don't know if you are using the segue to transition from one view controller to another. – El Tomato Mar 18 '17 at 02:03
  • @ElTomato VC1 has a UITableView and the dataSource for it is the array. The TableViewCells are filled just after the array is filled. VC2 is a data entry to the context, where I can add/save data. I'm trying to access VC1's array property to keep tracking on its indices. I'm using storyboard yes, and I can navigate to VC2 by using BarButtonItem in the NavigatioController using Push segue. – Ennabah Mar 18 '17 at 02:07
  • 1
    The problem is that `let vc1 = VC1()` creates a new instance of VC1, unrelated to the instance from which you segued. Because the new instance has not been presented, none of the viewDidLoad, viewWillAppear or viewDidAppear methods are called. So coreDataObjects will always be empty for that instance. Rather than trying to find a way to populate that instance, you should instead find a way to get a reference to the VC1 instance from which you segued. See [this question and the numerous answers](http://stackoverflow.com/q/5210535) for how to do that. – pbasdf Mar 18 '17 at 08:50
  • Thanks for the hint. I've created an array in VC2 that will hold the exact same array in VC1 when a segue is performed. The opposite is happening too, whenever I perform unwinding segue, I assign the VC1's array to the VC2's array. I do it this way because I want to keep tracking of the array's elements' indices. Please let me know if you have an enhanced way to do that. Thanks again! @pbasdf – Ennabah Mar 18 '17 at 17:35

1 Answers1

1

Here is the solution:

class VC1: UIViewController {
    lazy var coreDataObjects = fetchRequestThatFillsTheArray() 

    func fetchRequestThatFillsTheArray() {
        //calling NSFetchRequest
    }
}

If you still want a solution on your original code, or you have issue to use fetchRequestThatFillsTheArray() in lazy . The you have to use NSNotification. Read Notification Programming Topics

--- UPDate for your comment----

You should change you code a little.

class VC1: UIViewController {
    lazy var coreDataObjects:[NSManagedObject] = self.fetchRequestThatFillsTheArray() 

    func fetchRequestThatFillsTheArray() -> [NSManagedObject] {
        //calling NSFetchRequest
    }
}

However, since you used self.property in your fetchRequestThatFillsTheArray(), you can't use this solution.

You have to use NSNotification. That means you send a notification when fetchRequestThatFillsTheArray() finished. And register the notification in vc2. When vc2 get the notification, it does what it wants.

Owen Zhao
  • 3,205
  • 1
  • 26
  • 43
  • So coreDataObjects now is not an array? Anyway, that's what I get when I user your solution: Cannot use instance member 'fetchRequestThatFillsTheArray' within property intializer; property intializer run before 'self' is available. – Ennabah Mar 18 '17 at 02:26
  • Thanks for the help, I'll read the notification docs, anyway, I don't use self.property in fetchRequestThatFillsTheArray(). I might be using it in another part of the code, does that affect the lazy initialization? – Ennabah Mar 18 '17 at 02:52
  • Please try `lazy var coreDataObjects:[NSManagedObject] = self.fetchRequestThatFillsTheArray()` – Owen Zhao Mar 18 '17 at 02:57
  • I can't do that – Ennabah Mar 18 '17 at 03:01