2015-04-28 13 views
8

Studiuję książkę programową Cel C w Big Nerd Ranch. widziałem kod jak poniżej:Deklaracja pod interfejsem w Objective C

@interface BNREmployee : BNRPerson 
{ 
    NSMutableArray *_assets; 
} 


@property (nonatomic) unsigned int employeeID; 
@property (nonatomic) unsigned int officeAlarmCode; 
@property (nonatomic) NSDate *hireDate; 
@property (nonatomic, copy) NSArray *assets; 

-(double)yearsOfEmployment; 
-(void)addAsset:(BNRAsset *)a; 
-(unsigned int)valueOfAssets; 

w tym kodzie, dlaczego deklarują NSMutableArray *_assets pod interfejsu? Czym to się różni od deklarowania go jako własności i do czego służy?

Wreszcie widzę, że w nieruchomości znajduje się NSArray *assets. Czy to w zasadzie jest takie samo jak NSMutableArray *_assets?

+7

Głosy i zamykane głosowanie są nieodpowiednie tutaj. Jest to całkowicie uzasadnione pytanie o coś specyficznego i subtelnego w jakimś kodzie, który nie jest oczywisty dla początkującego użytkownika. –

+0

To jest dobre pytanie. Przeredagowałem ją nieco, by odeprzeć "opinię" blisko głosów. – vcsjones

+0

IMHO na to pytanie trudno odpowiedzieć. Wymaga to zrozumienia doskonale kluczowych pojęć Obj-C: czym jest własność i czym jest ivar, jak własność jest syntetyzowana, co to jest interfejs, co jest kontynuacją klasy ... i musisz także coś wiedzieć o historii Obj-C. Niełatwe do wyjaśnienia początkującym. – Sulthan

Odpowiedz

1
Nie jestem pewien, dlaczego to zrobili, ale jako ogólną dobrą praktykę, nie powinieneś robić tego sam. Plik nagłówkowy powinien być zarezerwowany dla publicznego interfejsu klasy. Umieszczaj tylko te rzeczy, które muszą wywoływać wywołujący i użytkownicy tej klasy, które na ogół będą właściwościami, metodami i być może stałymi extern.

Następnie pojawia się pytanie, czy użyć właściwości lub zwykłej zmiennej instancji. Jest to w dużej mierze zależne od preferencji. Niektórzy ludzie deklarują właściwości wszystkiego i nie używają w ogóle zwykłych kropek. Inni używają ivars dla wszystkiego i tylko właściwości, gdy chcą zadeklarować niestandardowy setter/getter dla danej zmiennej. Jestem w tym drugim obozie, ale można argumentować, że jest jaśniejszy i łatwiejszy do odczytania, jeśli wszystko jest tylko własnością.

edit

I błędne odczytanie kodu. To, co mówię powyżej, stoi normalnie, ale to, co robią, polega na tym, że eksponuje API, który różni się od danych podstawowych. Edytuję teraz odpowiedź.

Gdy deklarujesz właściwość bez niestandardowego @synthesize i bez przesłonięcia zarówno settera, jak i gettera, jeśli są one odpowiednie, tworzona jest zmienna bazowa z podkreślnikiem z przodu. To, co robią, polega na zwracaniu wartości NSArray w publicznym interfejsie API, aby upewnić się, że zmienna wewnętrzna nie jest modyfikowana, podczas gdy wewnętrznie używa się NSMutableArray.

Powiedziałbym, że ogólnie rzecz biorąc, ta deklaracja zmiennej (NSMutableArray *_assets;) powinna nadal znajdować się w pliku implementacji. Dzwoniący prawdopodobnie nie powinien wiedzieć, że jest zmienny pod maską.

Istnieje już wiele istniejących pytań dotyczących tego. Oto zapytanie z wieloma z nich: https://stackoverflow.com/search?q=mutable+ivar+immutable+property

0

Kluczową ideą jest to, że zmienna instancji ma inny typ niż deklaracja właściwości: jest zmienna, a deklaracja właściwości jest niezmienna.

+0

napisałeś źle. Zmienna instancji jest niezmienna, a właściwość zmienna. –

+0

@SamB dlaczego? Spójrz na 'ivar': ma on typ' NSMutableArray', tzn. Zmienny, a deklaracja właściwości zawiera tylko 'NSArray' - jest niezmienna. Gdzie się mylę? – Azat

2

Tutaj jesteś deklarując zmienną instancji o nazwie _assets:

@interface BNREmployee : BNRPerson { 
    NSMutableArray *_assets; 
} 

można teraz używać tej zmiennej w ramach realizacji swojej klasie:

_assets = @[ @1, @2, @4 ].mutableCopy; 
NSLog(@"The Answer is %@.", _assets[0]); 

Jednak zmienne instancji są prywatne w Cel-C, który jest dobry, jeśli nie chcesz, aby cokolwiek innego miało do niego dostęp. Ale co, jeśli potrzebujesz innych klas, aby móc uzyskać dostęp i/lub zmienić assets?

W przeważającej części będziesz chciał użyć właściwości iVar.

Korzystając z właściwości, automatycznie tworzymy ustawiające i pobierające, co oznacza, że ​​można ją przesłonić w celu dostosowania i wykorzystać w innych klasach (jeśli są one umieszczone w pliku nagłówka .h).

@property (nonatomic, assign) NSMutableArray *assets; 

NSMutableArray jest tylko zmienny (edytowalne) odpowiednik NSArray, to oznacza, że ​​możemy modyfikować wartości tablicy poprzez wstawienie nowych, usuwanie starych i przenoszenie indeksy dookoła.