Zaczęło się od zabawy z liczeniem hashy md5. Chciałem napisać program, który policzy hash dla każdego, nawet dowolnej wielkości pliku, jednak sposób który zastosowałem na początku skończył się tym, że program alokował ogromne ilości pamięci ze względu na użycie metody NSData dataWithContetsOfFile: (przy dużych plikach oczywiście). Md5 da się jednak policzyć po kawałku, więc zabrałem się za przystosowywanie programu.
Sam program nie byłby ciekawy gdyby nie jedno moje spostrzeżenie: warto używać NSAutoreleasePool w celu oszczędzania pamięci. Podam teraz przykładowy kod.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *data = [fileHandle readDataOfLength:MLDataSize];
while ([data length] > 0)
{
// Tu coś robimy np. po kawałku liczymy md5
[pool release];
pool = [[NSAutoreleasePool alloc] init];
data = [fileHandle readDataOfLength:MLDataSize];
}
[pool release];
Można to też napisać bez alokowania co chwilę NSAutoreleasePool, ale zaraz pokażę, dlaczego jednak warto to zrobić. Uruchomiłem obie wersje programu przy użyciu Instruments.
Powyżej jest screenshot pokazujący alokacje bez użycia NSAutoreleasePool
Powyżej jest screenshot pokazujący alokacje z użyciem NSAutoreleasePool
Na pierwszym zrzucie ekranu widać, że program alokuje duże ilości pamięci i po obliczeniu Md5 je zwalnia. Na drugim zrzucie widać, że program co chwilę alokuje niewielką ilość pamięci, wykonuje operacje i zwalnia ten kawałek, co jest moim zdaniem lepsze, bo wtedy program nie zużywa dużej ilości pamięci.
Kiedy pojawi się dialog odczytu/zapisu1 plików to po naciśnięciu ~ lub / otworzy się kolejny zatytułowany “Idź do katalogu”. Bardzo fajna funkcjonalność.
Jak zwykle bywa z takimi ukrytymi ficzerami, trafiłem na niego przez przypadek.
Tekst z wykładu pt. Algebra, choć z algebrą nie jest związany. Niestety dosłownie nie pamiętam1 Na wykładzie tłumów nigdy nie ma, nie było i nie będzie. Kierunek też dość niszowy, informatyka, więc pań dużo nie ma. A teraz do sedna:
- Na sali dwie samice.
- Normalnie serce staje.
- Mnie tam staje co innego.
Dzisiaj skalibrowałem sobie baterię i zauważyłem, że jej pojemność trochę spadła. Początkowo postanowiłem stale monitorować poziom zużycia baterii, ale szybko zmieniłem zdanie.
Sprzęt to w końcu tylko sprzęt, a w moim laptopie baterię można łatwo wymienić. Sprzęt ma być wygodny i łatwy w użyciu. I taki jest, tylko sporo ludzi przejmuje się baterią, jakby nie wiem co to było.
Apple jednak w jakimś celu nie wyświetla zużycia baterii domyślnie1, więc chyba jest jakiś tego powód, myślę że chodzi o to, żeby użytkownik nie zaprzątał sobie głowy takimi rzeczami, tylko wykorzystywał sprzęt, tak jak potrzebuje.
Pewnie z tego powodu Apple wprowadziło tylko takie “stopnie” zużycia baterii.
Normalny: Baterie funkcjonują prawidłowo.
Wymień wkrótce: Bateria działa prawidłowo, lecz przechowuje mniej ładunku, niż wtedy, gdy była nowa.
Wymień teraz: Bateria działa prawidłowo, lecz przechowuje znacznie mniej ładunku, niż wtedy, gdy była nowa. Bez szkody dla komputera nadal można używać baterii, aż zostanie wymieniona.
Wymaga naprawy: Bateria nie działa prawidłowo. Zmiany w jej zachowaniu i ilości przechowywanego ładunku mogą być lub nie być widoczne. Komputer powinien zostać sprawdzony przez autoryzowany serwis Apple. Bez szkody dla komputera nadal można używać baterii przed jej sprawdzeniem.
Da się do tej informacji dogrzebać w Profilu Systemu. ↩
Temat znowu związany z programowaniem na Mac. Nie ukrywam, że sporo czerpałem z tekstu Matt’a, który to tekst pozwolił mi dobrze wgryźć się w temat i napisać kontroler okienka preferencji. Parę fragmentów kodu może wyglądać podobnie – kod zmiany rozmiaru okna jest “jedyny słusznie działający”. Klasa umożliwia stworzenie okna preferencji w jednym nibie/xibie, a wszystkiego dokonuje się w Interface Builderze. Wystarczy trochę poklikać. Poniżej widać efekt końcowy.
Poniżej znajduje się opis sposobu użycia klas we własnym projekcie. Jeszcze się nie znajduje, ale się pojawi w weekend.
Aktualizacja
Dodałem możliwość ustawienia panelu, którego rozmiar może się zmieniać. Tutorial niestety nie w ten weekend z powodu braku czasu – kolokwium się zbliża.
Dzisiaj o pierwszej w nocy ruszył kolejny MacHeist.
Tym razem za darmo dostajemy programy WriteRoom, Twitterific, TinyGrab, ShoveBox, Hordes of Orcs (gra typu tower defence) oraz program Mariner Write, który zostanie odblokowany po pobraniu 500 000 paczek. Na chwilę obecną liczba pobranych paczek przekroczyła 30 000. Pobieranie będzie możliwe jeszcze przez 6 dni, a wartość całej paczki, którą otrzymujemy za $0.00 to $154.
Na początku miałem wątpliwości czy taki program może być do czegoś przydatny, ot taki sobie programik wyświetlający na ładnym grafie foldery i zajmowane przez nie miejsce. Och, jakże się myliłem, program jest wielce przydatny, pozwolił mi bowiem zaoszczędzić trochę miejsca na dysku. 4GB to jednak jest coś, szczególnie gdy jest się człowiekiem z natury walczącym o każdy megabajt wolnej przestrzeni.
Program ten uświadomił mi, że trzymanie starych wiadomości z kanałów RSS może zająć dość sporo miejsca. Podobnie było jeszcze z kilkoma folderami na dysku, których zawartości nie omieszkałem się pozbyć.
Podsumowując, bardzo fajny, odpicowany graficznie i bardzo pomocny programik. Aha na macheist jest za darmo, no prawie, bo za tweetnięcie.
Użycie jest całkiem proste, działa tylko dla tablic jednowymiarowych, ale można je przecież zagnieździ. Podejrzewam, że ten kod optymalny nie jest, ale nie bardzo mam pomysł jak usunąć tą drugą, wewnętrzną pętlę.
Znalazłem na Stack Overflow, lekko zmodyfikowane, żeby nie trzeba było robić foreach(int *i, tab). Tak jak jest jest trochę ładniej i prościej. Poprawka w sumie wcale nie pomogła, dlatego przywróciłem kod do oryginału. Jeśli chcemy pętlę zagnieździć to musimy zrobić to w taki sposób
Siedzę już jakiś czas i próbuję jeszcze bardziej uprościć ten kod bez okrajania funkcjonalności i powoli zaczynam dochodzić do wniosku, że to jest najlepsze rozwiązanie.