Похоже, что sortedArray
равно nil
или имеет счет сохранения нуля, и это сбивает с толку отладчик в отношении его класса. Я видел это в своем собственном коде, когда позволил этому случиться: ваша проблема связана с использованием =
без self
в поле зрения, и поэтому вы, вероятно, создаете зомби. В случае сомнений запустите Анализатор в «Продукт -> Анализ» (XCode 4. *).
Чтобы исправить проблему, вам нужно использовать синтезированные геттеры и сеттеры. В вашем интерфейсе я рекомендую объявить что-то вроде:
@property(retain) NSArray * sortedArray;
и кое-где в вашей реализации:
@synthesize sortedArray;
Тогда вместо sortedArray = [arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
, что плохо, поскольку он обходит все удержания, выполните:
[self setSortedArray:[arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]];
или
self.sortedArray = [arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
Они эквивалентны. Хотя =
появляется во втором варианте, компилятор распознает это как вызов установщика, правильно управляя счетом сохранения.
Наконец, в методе dealloc
вашего подкласса вы должны освободить sortedArray
перед вызовом dealloc
для super
, иначе у вас будет утечка памяти.
В общем, я бы покончил с ivar
s как можно больше, за исключением управления каким-то внутренним состоянием для вашего пользовательского объекта, который должен быть закрытым. Если по умолчанию вы звоните, скажем, [self myMember]
или [self setMyMember:]
, вы дисциплинируете себя и избавите себя от стресса, вызванного этой ошибкой.
Если вы чувствуете себя особенно уверенно, лично я бы переопределил установщик для вашего массива с помощью чего-то вроде:
- (void) setSortedArray:(NSArray *) anArray
{
// Make this thread safe by surrounding with a lock.
@synchronized(self)
{
// Always retain the new before releasing the old, in
// case the old and new are the same object!
[anArray retain]
[self.sortedArray release];
// Set the data array; we don't call on self here.
sortedArray = anArray;
// UIKit is not thread safe so we push the reload
// call onto the main thread; blocks only work in
// iOS4.1 and up, otherwise perform selector in
// the background:
// [self.tableView performSelectorInBackground:@selector(reloadData) withObject:nil];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the table
[self.tableView reloadData];
}];
}
}
Также объявите собственность с
@property(nonatomic, assign, setter = setSortedArray:) NSArray * sortedArray;
Вам нужно nonatomic
здесь, так как компилятор не может обещать, что ваш пользовательский установщик будет поточно-ориентированным. (Вместо этого мы гарантируем, что он потокобезопасен.) В любом случае вы все равно сможете компилировать, но компилятор предупредит вас об этом.
Примечание. Я не тестировал приведенный выше код, я написал его в коробке SO.