2013-04-03 3 views
3

Я разрабатываю приложение iOS с последним SDK.Двойной @синхронизированный: он нужен?

Мое приложение является портом из Android приложения и у меня есть эти два метода:

- (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); 
    } 
} 

Я имею isMyObjectVisible:, то есть @synchronized, вызов другой @synchronized метод.

Необходимо, чтобы isMyObjectVisible: должен был быть @synchronized?

+0

Возможно, вы это делаете ** Просто для обеспечения безопасности потоков **. Просим прочитать [@synchronized and threadSafety] (http://stackoverflow.com/questions/15392726/does-synchronized-guarantees-for-thread-safe-or-not) –

+0

Вы пробовали? Это похоже на немедленный тупик для меня ... – borrrden

+0

@borrrden, замок в этом случае является * рекурсивным *, поэтому он не затормозит программу. Это просто лишний и немного расточительный. – Nate

ответ

1

Чтобы ответить на ваш первый вопрос, нет, двойная блокировка не требуется.

Вы можете оставить замок в getMyObject. Это защищает его. Однако в isMyObjectVisible ничего не найдено, кроме звонка getMyObject, поэтому ничего нет еще для защиты в этом методе.

Однако комментарий borrrden не является проблемой здесь. Вы получаете recursive lock, когда using @synchronized, так что вы можете вложить synchronized звонки, как будто вы делаете без взаимоблокировки. Просто нет нужно, в вашем случае.

1

Вот пример того, что вы должны использовать двойной @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); 
      } 
     } 
} 

(ул является статическим переменным) -Постарайтесь запустить его без @synchronized (я) и посмотреть, что произойдет.

Смежные вопросы