0

Thanks to Lock a NSMutableArray of an object but not the rest of my object when using GCD I have a user object that populates an array of locations via gcd at init in the hope that by the time we modally get to LocationViewController the locations are present in user.locations (where user is passed along the viewcontrollers), if they aren't there then I simply display 'loading...' in the picker.

I would ideally like to force a refresh from within the gcd of user in the dispatch_sync method. I can added a method to LocationViewController that will refresh the picker etc but I'm not sure how to then safely access this.

My first thought was in LocationViewController if the locations aren't there (i.e. nil) then to set a reference to this LocationViewController in user. Within the dispatch_sync I could then call the method [locCont mymethod] if locCont isnt nil. But I'm not sure how to set up the property in the user class?

@property (strong, nonatomic) LocationsViewController * locCont;

What worries me is a user can at anypoint logout and return to the root view. I'll then set

user.locCont = nil

will ARC sort any hungover memory nicely?

My other concern is what will happen if they don't choose to set a location and are on a later view. I guess I could handle that by setting user.locCont to nil in a prepareforsegue.

Is there a better way to get the LocationsViewController to refresh if the user has got there?

Community
  • 1
  • 1
Adam Knights
  • 2,141
  • 1
  • 25
  • 48

2 Answers2

2

I would suggest to use notifications to avoid a strong connection between the "User" object and a view controller.

The LocationViewController would register for a custom notification in its init method and unregister in dealloc.

The GCD code "posts" the notification when it is finished. That causes all listeners to be notified, so that the LocationViewController can refresh its view.

See the NSNotificationCenter documentation, and Send and receive messages through NSNotificationCenter in Objective-C? for good sample code that should help for a start.

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • +1, good logic, though I would probably use a delegate, since, more than likely, there will only be one controller on the screen with a location list to update. – user352891 Jul 31 '13 at 20:27
  • Going to mark this as answer - one question - if you had two objects both marked as observers would both objects' methods get called or do they compete? – Adam Knights Aug 01 '13 at 07:51
  • @Knightsy: All observers are notified independently, so both would be called. – Martin R Aug 01 '13 at 07:54
0

If you have retrieval of data happening asynchronously by some user object, and you want view controllers to get access to this object, you would generally maintain some external reference to this user object. One common approach would be to make this user object a singleton. Another would be to make it a property of the app delegate. Either way, the user object probably would not maintain a reference to any view controllers. The user object would just be in the business of retrieving the information asynchronously, view controllers could access the current state of the user object through either the singleton or the app delegate.

If you want the user object to be able to inform view controllers when the data retrieval is done, you'd probably have it post a notification via the notification center. View controllers could register themselves to observe those notifications (and, before a view controller dismisses itself, remove itself as an observer of that notification).

Rob
  • 415,655
  • 72
  • 787
  • 1,044