/ / Objective-C - Praca z subviewsami - target-c, uiview, uitableview

Objective-C - Praca z subviewsami - target-c, uiview, uitableview

Jestem nieco zdezorientowany UITableViewCell stworzyć własny projekt komórki. w -initWithStyle: metoda. Zajmuję się konfiguracją UILabels tak:

self.careerTitleLabel = [[UILabel alloc] init];
[self.contentView addSubview:careerTitleLabel];
[self.careerTitleLabel release];

Następnie umieść etykietę, w której to robię -layoutSubviews jak na przykład:

CGRect careerTitleLabelFrame = CGRectMake(10, 10, 280, 20);

self.careerTitleLabel.frame = careerTitleLabelFrame;

Ten kod faktycznie działa. Ustawia moją etykietę tam, gdzie chcę ją ustawić. Ale nie rozumiem tego W JAKI SPOSÓB to działa. Ponieważ właśnie modyfikuję ramę karieryTitleLabel ivar, a nie karieręTitleLabel, która została dodana jako subView do contentView.

Moim założeniem byłoby zmodyfikowanie ramki etykiety, którą dodałem do contentView, musiałbym ją wyciągnąć za pomocą -viewWithTag: a następnie zmodyfikuj tę ramkę. W tej chwili modyfikuję tylko Iwara klasy?

P.S Kolejnym niezwiązanym z tym pytaniem problemem jest, dlaczego self.careerTitleLabel ma po 2 wypłaty 2 rat? D.S

Odpowiedzi:

3 dla odpowiedzi № 1

addSubview: nie kopiuje widoku, przez który go przechodzisz, zachowuje go, więc kiedy go zwolnisz, nie zostanie faktycznie przydzielony. Jest żywy, ponieważ self.contentView wciąż go używa. Oznacza to, że twoje odniesienie do self.careerTitleLabel nadal działa, chociaż myślę, że większość uznałaby to za zły styl, uzasadniając to tym, że powinieneś przechowywać odniesienia do obiektów, które zamierzasz później przesłać, zamiast przypisywać wiedzę z wzorców własności używanych gdzie indziej.

retainCount nigdy nie można polegać absolutnie. Jest też nieprzejrzysty jak dużo addSubview: zwiększy liczbę zatrzymań o, inne niż to, że będzie to co najmniej 1. To powiedziawszy, najbardziej prawdopodobny powód, dla którego jesteś careerTitleLabel jako właściwość i mają linię typu:

NSLog(@"%d", [self.careerTitleLabel retainCount]);

Czy to standardowy getter to:

return [[careerTitleLabel retain] autorelease];

Tak więc liczba zatrzymań jest tymczasowo zwiększona ogetter, rozumując, że wyniki modułów pobierających powinny być co najmniej tak długie, jak pula autoreleaseów - nawet jeśli obiekt, z którego je otrzymałeś, jest wcześniej przydzielany.


1 dla odpowiedzi nr 2

careerTitleLabel jest wskaźnikiem do obiektu. Więc kiedy to zrobisz addSubview: careerTitleLabel, kod, do którego dzwonisz, zawiera odniesienie do careerTitleLabel.

Później, po włączeniu ramki careerTitleLabel w layoutSubviews, aktualizujesz ten sam obiekt.

layoutSubviews jest absolutnie odpowiednie miejsce, aby to zrobić. Jest wywoływany automatycznie na początku i ponownie, jeśli zmieniają się widoki, na przykład, jeśli orientacja urządzenia się zmieni.

viewWithTag to inny sposób dostępu do wydziału. Osobiście uważam, że utrzymanie ivar jest czystsze. Nie zapomnij, że możesz używać IBOutletów do podłączania tych rzeczy przy użyciu Kreatora interfejsu.

Wreszcie masz problem z pamięcią i towyjaśnia, że ​​zatrzymanie się liczy. Dobrze jest przeprowadzić Analizę często, aby wykryć te problemy, a także profilować za pomocą Instrumentów za pomocą przecieków. Możesz nawet ustawić flagę w ustawieniach kompilacji, aby zawsze uruchamiać Analizę przy każdym budowaniu.

Tak czy inaczej tutaj jest problem:

self.careerTitleLabel = [[UILabel alloc] init];

Jeśli twoja własność w pliku .h jest skonfigurowana jak:

@property (nonatomic, retain)

wtedy będziesz się nad nimi zatrzymywał. Zachowasz dwa razy, co spowoduje problemy z pamięcią.

Wytyczne Apple zalecają, abyś nigdy ich nie wywoływałsetery w metodzie init. Na tym etapie zachowanie może być nieprzewidywalne, ponieważ możesz przechodzić przez niestandardowy zestaw, niezależnie od metody, podczas gdy twój obiekt nie zakończył jeszcze swojego init.

O wiele bezpieczniej jest mieć:

    careerTitleLabel = [[UILabel alloc] init];

Jeszcze lepiej, w swoim pliku .h przedrostek ten z "m" dla zmiennej członka. Wtedy będziesz miał

    mCareerTitleLabel = [[UILabel alloc] init];

W syntezie użyj:

    synthesize careerTitleLabel = mCareerTitleLabel;

To oznacza, że ​​z zewnątrz - lub wewnątrz - Twój kod, możesz uzyskać dostęp do tego jako:

    self.careerTitleLabel

lub

    myObjectName.careerTitleLabel

Mam nadzieję, że to pomoże! To dużo do pokrycia!