3

I'm developing an iOS application with latest SDK.

My app is a port from an Android application and I have these two methods:

- (MyObject*)getMyObject:(MyObjectType)myObjectType
{
    @synchronized(self)
    {
        for (int index = 0; index < [myObjects count]; index++)
        {
            MyObject* myObject = (MyObject*)[myObjects objectAtIndex:index];
            if (myObject.Type == myObjectType)
                return myObject;
        }

        return nil;
    }
}

- (BOOL)isMyObjectVisible:(MyObjectType)myObjectType
{
    @synchronized(self)
    {
        return ([self getMyObject:myObjectType] != nil);
    }
}

I have isMyObjectVisible:, that is @synchronized, calling another @synchronized method.

Is it necessary that isMyObjectVisible: has to be @synchronized?

Nate
  • 31,017
  • 13
  • 83
  • 207
VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • You are probably doing this **Just to be sure of thread safety**. Kindly read [@synchronized and threadSafety](http://stackoverflow.com/questions/15392726/does-synchronized-guarantees-for-thread-safe-or-not) – Anoop Vaidya Apr 03 '13 at 09:04
  • Have you tried it? It looks like an immediate deadlock to me... – borrrden Apr 03 '13 at 09:05
  • @borrrden, the lock in this case is a *recursive* one, so it won't deadlock the program. It's just unnecessary, and slightly wasteful. – Nate Apr 03 '13 at 09:35

2 Answers2

1

To answer your first question, no, the double locking is not needed.

You can keep the lock in getMyObject. That protects it. However, there is nothing in isMyObjectVisible other than a call to getMyObject, so there's nothing else to protect in that method.

However, borrrden's comment is not an issue here. You get a recursive lock when using @synchronized, so you can nest synchronized calls like you're doing without a deadlock. There's just no need to, in your case.

Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207
1

Here is an Example of that you need to use double @synchronized :

NSString * str;
str = [[NSString alloc] initWithFormat:@"str"];

-(void)viewDidLoad{

  NSString *foo = @"foo";
  NSString *bar = @"bar";
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  [self firstAction:foo];
  });
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  [self secondAction:bar];
  });
}
- (void)firstAction:(NSString *)sender {
    NSLog(@"firstAction");
    @synchronized (self) {
        str = sender;
        for (int i=0; i<5; i++) {
            NSLog(@"first: %@",str);
        }
    }
}

- (void)secondAction:(NSString *)sender {
        NSLog(@"secondAction");
        @synchronized (self) {
            str = sender;
            for (int i=0; i<5; i++) {
                NSLog(@"second: %@",str);
            }
        }  
 }

(str is static variable ) -Try to run it without the @synchronized (self) and see what will happen.

Almog_0
  • 422
  • 4
  • 11