2013-01-04 8 views
5

Czy można wymusić na kompilatorze Xcode potwierdzenie, że pliki wymienione w kodzie są ważne?Sprawdzanie czasu kompilacji dla poprawnego pliku referencyjnego w Xcode

Istnieje wiele punktów w rozwoju Cocoa kiedy naturalnie odwoływać plik programowo poprzez NSString:

[UINib nibWithNibName:@"MyNib" bundle:nil]; 
[UIImage imageNamed:@"MyImage"]; 
[[UIViewController alloc] initWithNibName:@"MyNib" bundle:nil]; 

Czy jest jakiś sposób w czasie kompilacji, by sprawdzić referencje tych plików jest to ważne?

Często po użyciu powyższych metod zmieniam nazwę pliku, do którego się odwołuje, ale zapomniałem zmienić nazwę w kodzie. Wszystko działa bez problemu i tylko wtedy, gdy zdarzy ci się przejść do części aplikacji, która uzyskuje dostęp do tego pliku, pojawi się błąd.

Czy istnieje inne podejście lub technika, której ludzie używają w celu uniknięcia tego rodzaju błędu?
Odwoływanie się do nazwy pliku za pomocą ciągu znaków jest bardzo delikatne.

+0

Dlaczego nie możesz użyć, jeśli-else konstruować, aby sprawdzić dostępność pliku w podanej ścieżce? –

+1

Nie dotyczy. Jeśli nazwa pliku się zmieniła, chcę o tym wiedzieć - nie chcę, aby obraz był pusty. – bearMountain

+0

AFAIK nie ma nic do powiedzenia, aby to sprawdzić podczas kompilacji. Bezpieczniejszym sposobem byłoby użycie stałych. – Andy

Odpowiedz

3

AutoComplete for [UIImage imageNamed:] od Kent Sutherland.
To zapewnia obsługę zakończenia kodu w Xcode - genialny kawałek kodu. Działa to dla mnie w Xcode 4.6: enter image description here

Obecnie ten projekt nie obsługuje ciągów innych niż imageNamed:. Aby je wspierać, postaram się napisać scenariusz kompilacji. A może odważę się i spróbuję rozszerzyć spektakularną pracę pana Sutherlanda.

+0

Przyjemne narzędzie, dzięki za udostępnienie. – Till

1

Xcode nie obsługuje tej funkcji, ale jeśli ten problem jest naprawdę gryzie cię to można użyć następującego Hack:

  • dać każdemu plikowi in Bundle unikalny prefiks (np app__)
  • Kiedy dodajesz plik do projektu, upewnij się, że najpierw zmieniłeś jego nazwę, aby dodać ten prefiks.
  • Kontrola czasu kompilacji (wstępnej dystrybucji) składa się z dwóch części: 1) Przeszukuj wszystkie pliki .m i wyliczaj ciągi zaczynające się od prefiksu. Nie powinieneś sprawdzać, czy ciąg znaków jest cytowany, ponieważ twój prefiks jest unikatowy. 2) grep project.pbxproj dla każdego ciągu, aby sprawdzić, czy jest on zawarty w pakiecie.

Z pewnym wysiłkiem proces ten może być w większości zautomatyzowany i zoptymalizowany, ale powyższy przepis powinien zadziałać.

3

Stalówki mają zazwyczaj klasę o tej samej nazwie co plik, np.

[[MyViewController alloc] initWithNibName:NSStringFromClassName([MyViewController class]) bundle:nil];

zwykle schować go do sterownika init metody jako [self class].

W przypadku ładowania obrazów kontrole podczas kompilacji są trudne. Pomóż sobie z makrami, najpierw zastąp metodę ładowania prostym makrem, np.

#define LOAD_IMAGE(__IMAGE_NAME__) [UIImage imageNamed:__IMAGE_NAME__]

Pierwszą rzeczą jaką należy zrobić, to położyć assert w tym makro i zawsze upewnić się, że obraz został pomyślnie załadowany. To nie jest kontrola podczas kompilacji, ale pomaga znaleźć brakujące zasoby.

Drugą sprawą jest napisanie skryptu ruby ​​/ python/shell/(dowolnego języka skryptowego), który przeszuka pliki źródłowe pod kątem LOAD_IMAGE i sprawdzi, czy plik (między nawiasami) istnieje. Jako skrypt powłoki będzie bardzo prosty (na przykład przy użyciu grep). Możesz dodać ten skrypt do swojego projektu xcode, który będzie uruchamiany podczas kompilacji. Nie zapomnij sprawdzić obrazów przywoływanych przez Xibs.

Jednak często trzeba dynamicznie utworzyć nazwę obrazu, np. NSString* imageName = [NSString stringWithFormat:@"image_%i", index]. Nie ma sposobu, jak to sprawdzić w czasie kompilacji.

Nie zapomnij również o sprawdzeniu wstecznym - nie dołączaj plików graficznych, które nie są używane nigdzie.

+0

Świetne rozwiązanie skryptowe - nie myślałem o tym podejściu. Chociaż w twoim pierwszym punkcie, '[[MyViewController alloc] init]' faktycznie przeszukuje twoje pliki i ładuje stalówkę jeśli ma ona nazwę, która pasuje do klasy 'MyViewController' (zgodnie z dokumentacją Apple). To może zaoszczędzić ci trochę kłopotów. – bearMountain

+0

@bearMountain Wiem o tym, miał problem z domyślnym wyszukiwaniem po dziedziczeniu kontrolerów od kontrolera podstawowego. Nie pamiętam dokładnie powodu, ale teraz używam '[self class]'. Nie jest to duży problem :) – Sulthan

1

Oto skrypt basha, którego używamy, który zawiera listę wszystkich obrazów na dysku, ale NIE są one przywoływane w kodzie. https://gist.github.com/3750087

Najprawdopodobniej łatwo byłoby odwrócić tę opcję, aby sprawdzić, czy obrazy nie są wygaszane i nie zawierają szumów. W każdym razie skrypt powinien być dobrym punktem początkowym