1

I have a User class which has various properties:

@property (strong, nonatomic) NSString *CandID;
@property (assign, nonatomic) BOOL IsCandidate;
@property (assign, nonatomic) NSInteger ResponseCode;
@property (strong, nonatomic) NSMutableArray *locations;

etc

One of my ViewControllers may have a user property i.e.

@property (strong, nonatomic) User *user;

And this user may be passed to subsequent ViewControllers which are launched modally.

When the user object is first initialized I am going to send some method off in grand central dispatch that will fill the locations array via REST. The idea is that by the time someone using my app gets to the screen to pick a location, the list will already be downloaded.

What I want to do is lock the locations area when the gcd is using it, I have used something like

[someLock lock] ... [someLock unlock]

in the past but what I want is the locations array to be locked but the rest of the user object's methods and properties to be accessible from the main thread. What is the best way to achieve this?

Adam Knights
  • 2,141
  • 1
  • 25
  • 48
  • 2
    A lock doesn't actually lock anything, it prevents entry to the guarded region. To have finer granularity you need smaller guarded regions. – Hot Licks Jul 31 '13 at 17:08
  • What are you trying to achieve? Are you trying to keep `locations` readonly until the block completes? – Brian Nickel Jul 31 '13 at 17:24
  • I want to prevent a situation where locations is half written or being written to by the gcd thread and then accessed from the main thread, Martins answer below seems to achieve that – Adam Knights Jul 31 '13 at 17:27

1 Answers1

4

I would fetch the locations in a background thread into a separate array, and only assign it to the user when the data is complete, something like:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSMutableArray *locations;
    // ... fill locations ...        
    dispatch_sync(dispatch_get_main_queue(), ^{
        user.locations = locations;
        // ... perhaps refresh some view or send a notification ...
    })
});

Then user.locations is always accessible on the main thread, and is either nil or contains the fetched locations.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382