1. Objective C / Говнокод #13165

    −99

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    - (void)initPlayerViewController
    {
    	BOOL isSuccess = NO;
    	do {
    		NSString *linkString = nil;
    		unsigned long long objectID = [_videoID intValue];
    		
    		int index = GetElementIndex(objectID, _WidevineTestStubs, WIDEVINE_TEST_COUNT);
    		if (index >= 0) {
    			//linkString = GetLink(_WidevineTestServers[index], _WidevineTestFiles[index]);
    			linkString = _WidevineTestLinks[index];
    		}
    		else {
    			linkString = GetString([_videoLink objectForKey:@"src"]);
    		}
    		if(linkString == nil)
    			goto _end;
    
    		self.linkType = GetLinkType(linkString);
    		switch (_linkType) {
    			case LINK_TYPE_HLS:
    				break;
    			case LINK_TYPE_WV_ADAPTIVE:
    			case LINK_TYPE_WV_MULTI:
    				linkString = WidevinePlay(linkString);
    				if ([linkString length] <= 0) {
    					goto _end;
    				}
    				break;
    			default:
    				goto _end;
    		}
    		
    		NSURL *link = [NSURL URLWithString:linkString];
    		if(link == nil)
    			break;
    
    		self.playerViewController = [[[MPMoviePlayerViewController alloc] initWithContentURL:link] autorelease];
    		_playerViewController.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
    		_playerViewController.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
    
    		NSInteger startPosition = GetInteger([_videoLink objectForKey:@"play_start_time"]);
    		if(startPosition > 0) {
    			_playerViewController.moviePlayer.initialPlaybackTime = (NSTimeInterval)startPosition;
    		}
    		
    		[self addControlsView];
    		NSArray *audioTracks = [_videoLink objectForKey:@"audio_list"];
    		if ([audioTracks count] < 2) {
    			UIButton *audioButton = (UIButton *)[_controlsView viewWithTag:TAG_BUTTON_CHANGE_AUDIO];
    			audioButton.enabled = FALSE;
    		}
    		
    		isSuccess = YES;
    	} while(0);
    _end:
    	if(isSuccess) {
    		[_delegate onPlayerCreated:self];
            [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
    	}
    	else {
    		[_delegate onLinkError:self];
    	}
    }

    Тут есть все, и do while(0), и проваливающиеся case'ы, и TRUE/FALSE, и глобальные inline методы, и даже goto.

    Запостил: ArtFeel, 13 Июня 2013

    Комментарии (15) RSS

    • Казалось бы, если автор знает выпендреж с do while(0), почему он все еще использует goto? Ну ладно, в switch break другое значение имеет, можно было на if заменить. Но в 17 строке то точно можно break сделать...
      Ответить
      • Это не единственный goto в приложении, а в do while там вообще почти все обвернуто.
        Ответить
        • А в Objective C есть finally?
          Ответить
          • конечно
            Ответить
            • Хм, тогда боюсь спрашивать, зачем нужно какирство с do { ... } while (0), если есть finally, которое срабатывает на return'ах?
              Ответить
      • На самом деле do { ... } while (0) намного более нечитабельная конструкция, нежели одна метка. Если отрефакторить ну уж совсем не удастся - лучше выкинуть ее, и заменить все бряки от него на goto _end. Имхо goto в таких случаях адекватней и понятней чем этот недоцикл.

        > проваливающиеся case'ы
        Строки 23-24? Так, извините, не паскаль. По-другому одно действие на 2 значения в свиче и не навесить.
        Ответить
        • По мне так и лесенка из if лучше будет.
          Ответить
          • Да не, одно goto в конец функции лучше, чем лесенка ифов или do { ... } while (0). В языках, в которых нет RAII или finally, goto вполне можно юзать, ибо других адекватных вариантов то и нет.
            Ответить
      • > почему он все еще использует goto
        Потому что внутри свич ;) А из него бряк уже не сработает.
        Ответить
        • > А из него бряк уже не сработает.
          Ну тогда надо бряк-бряк.

          А если серьезно - то рефакторинг онли.
          Ответить
          • > Ну тогда надо бряк-бряк.
            Ну да, в жабе вот сделали бряк на метку. Такой вот узаконенный goto в один конец. Как раз для таких случаев. А называется бряком чтобы готофобы и готохейтеры не возмущались и не сцали его юзать.

            > А если серьезно - то рефакторинг онли.
            +100500. Безусловно, этому коду рефакторинг не помешает.
            Ответить
            • В жабе метки могут стоять только в начале блока, так что не надо.
              Ответить
              • Так я и пишу: goto в один конец. А где метка стоит - не суть. Это скорее всего тоже для отвлечения готохейтеров. А по семантике это самое настоящее ограниченное goto. Одно из тех его применений, которые я признаю в сишном коде.
                Ответить
                • >А где метка стоит - не суть.
                  Таки суть. Метки в яве могут использоваться только для выхода из вложенных циклов. Концепцию вложенных блоков они не нарушают. А вот нахуя их вернули в сисярпе - хз.
                  Ответить
                  • > Концепцию вложенных блоков они не нарушают.
                    А ну да, обычное goto может еще на середину блока прыгать, ок.
                    Ответить

    Добавить комментарий