Dlaczego (kopiująca, nieatomiczna) właściwość NSMutableArray tworzy nsarrays?
Popełniłem błąd podczas tworzenia widoku TableView class
i przypadkowo zachowałem @property
jako copy
Kiedy go zdefiniowałem:
@property (copy, nonatomic) NSMutableArray *words;
Zainicjalizowałem tablicę "poprawnie": (zauważ, że jest to trzecia próba, więc proszę zignorować fakt, że nie używam mutableCopy i innych lepszych sposobów na to)
NSArray *fixedWords = @[@"Eeny", @"Meeny", @"Miny", @"Moe", @"Catch", @"A", @"Tiger", @"By", @"His", @"Toe"];
NSMutableArray *mutWords = [[NSMutableArray alloc] initWithArray:fixedWords];
self.words = mutWords;
Jednak, kiedy później przyszedłem zmienić kolejność tablicy, rozbiła się na linii removeObjectAtIndex:
id object = [self.words objectAtIndex:fromIndexPath.row];
NSUInteger from = fromIndexPath.row;
NSUInteger to = toIndexPath.row;
[self.words removeObjectAtIndex:from];
Z Komunikatem o błędzie
unrecognized selector sent to instance
Zajęło dużo kopania do dowiedz się, że dzieje się tak, ponieważ kopia oznacza, że przypisanie NSMutableArray powoduje utworzenie standardowego (niemutable) NSArray. Czy ktoś może wyjaśnić, dlaczego jest to prawidłowe zachowanie?
2 answers
- Kopia, zaimplementowana przez zmienne klasy Cocoa, zawsze zwraca ich niezmienne odpowiedniki . Tak więc, gdy wysyłana jest kopia NSMutableArray, zwraca ona NSArray zawierający te same obiekty.
Ponieważ words
ma kwalifikator pamięci copy
, Ta linia:
NSMutableArray *mutWords = [[NSMutableArray alloc] initWithArray:fixedWords];
self.words = mutWords;
Rozszerza się do:
NSMutableArray *mutWords = [[NSMutableArray alloc] initWithArray:fixedWords];
self.words = [mutWords copy];
Biorąc pod uwagę, że NSMutableArray jest podklasą NSArray, kompilator nie narzeka, a Ty masz teraz tykającą bombę na rękach, ponieważ NSArray nie rozpoznaje jest to metoda mutowalna podklasy (ponieważ nie może zmutować jej zawartości).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-13 15:24:50
Właściwości nie są magiczne, są tylko skrótem. Deklaracja @property
na Twoim obiekcie mówi kompilatorowi, aby stworzył zmienną instancji pomocniczej i metody dostępu do niej. Rzeczywisty wygenerowany kod zależy od atrybutów ustawionych na właściwości.
Ważne jest, aby pamiętać, że Ustawianie właściwości za pomocą składni kropki jest również skrótem. Kiedy dzwonisz ...
self.words = mutWords;
...wywołujesz wygenerowaną metodę accessor za kulisami, jak to:
[self setWords:mutWords];
Ponieważ podałeś atrybut copy
na swojej właściwości, kazałeś kompilatorowi wygenerować metodę -setWords:
accessor z kodem, który wygląda mniej więcej tak:
- (void)setWords:(NSMutableArray *)words
{
_words = [words copy];
}
Wiedząc to wszystko, możesz zobaczyć, co się dzieje: wygenerowana metoda setter wywoła -copy
na argumencie wejściowym i przypisze wynik do zmiennej instancji wspierającej. Ponieważ metoda -copy
jest zawsze zaimplementowana w celu zwrócenia obiektu niemutowalnego (wykonanie [aMutableString copy]
zwróci NSString, itd.) ustawienie tej właściwości zawsze będzie przechowywać kopię niemutowalną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-14 19:14:14