2014-01-25 8 views
1

Я замечаю, что у Apple есть то, что кажется дублирующими именами: 2 свойства и два ivars. Почему Apple делает это?Почему Apple использует как частные вары, так и свойства с тем же именем в примере кода рецептов?

//.h file 
@interface TypeSelectionViewController : UITableViewController { 
    @private 
     Recipe *recipe; 
     NSArray *recipeTypes; 
} 

@property (nonatomic, retain) Recipe *recipe; 
@property (nonatomic, retain, readonly) NSArray *recipeTypes; 

Затем они обновляют экземпляр рецепта ниже. Почему есть две переменные с тем же именем? Будет ли влиять на переменную рецептуры parentViewController, так как эта переменная рецепта была задана при представлении этого контроллера вида, код которого находился от parentViewController?

//.m file 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    // If there was a previous selection, unset the accessory view for its cell. 
    NSManagedObject *currentType = recipe.type; 

    if (currentType != nil) { 
     NSInteger index = [recipeTypes indexOfObject:currentType]; 
     NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:index inSection:0]; 
     UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath]; 
     checkedCell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    // Set the checkmark accessory for the selected row. 
    [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];  

    // Update the type of the recipe instance 
    recipe.type = [recipeTypes objectAtIndex:indexPath.row]; 

    // Deselect the row. 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

UPDATE 1

Этот код из iPhoneCoreDataRecipes ядра, например данных от Apple:

Сначала посмотрим на метод делегата RecipeViewController's didSelect, который представит TypeSelectionViewController (ребенка) контроллер представления , Затем рассмотрите способ делегата viewcontroller didSelect, где вы найдете реализацию кода.

Причина, по которой я начал смотреть на это, потому что мне было интересно, как ячейка tableView родителя обновилась в соответствии с выбором в ChildViewController в режиме редактирования.

Чтобы увидеть это для себя, сделайте следующее:

  1. Запустите приложение
  2. Выберите вкладку Recipes
  3. Нажмите на рецепт - Шоколадный торт.
  4. Нажмите кнопку «Изменить» в правом верхнем углу
  5. Обратите внимание на текущую категорию - должно быть в пустыне - затем нажмите на нее.
  6. Затем вас отвезут в контроллер детского зрения
  7. Нажмите на другую категорию, затем нажмите назад, и вы заметите, что кнопка категории для этого рецепта волшебным образом обновлена. И я не знаю, как это происходит.

Связано ли это с частными иварами и свойствами? который влияет на ячейку parentViewController?

Мой вопрос i Угадайте, как выбор типа категории в таблице контроллера детского просмотра влияет на cell.text в таблице контроллера родительского контроля? Я не вижу, где управляемый объектбезопасность сохраняется в контроллере дочернего представления, чтобы он автоматически обновлял текст ячейки родительского элемента View.

+0

Где находится этот образец кода? Могу ли я увидеть полную реализацию? – nhgrif

+0

Да, пожалуйста, проверьте обновленное сообщение, где я разместил ссылку – Pavan

+0

. В верхней части .m должна быть строка, которая говорит '@synthesize recipe = recipe; @syntehsize recipeTypes = recipeTypes; 'Это только более старый код, прежде чем он изменил его, чтобы сделать большую часть этой работы для вас в фоновом режиме. – Putz1103

ответ

3

Что вы видите здесь, это относительно старый код, и этого больше не нужно, благодаря автоматическому синтезу Objective-C.

В настоящее время, когда вы выдаете @property (nonatomic) NSArray *foo;, вы неявно получить @synthesize foo = _foo; в файле реализации и объявление переменной экземпляра в вашем заголовке. Вы не видите этого, компилятор «вставляет» его автоматически. foo - это номер property и _foo.(В приведенном выше примере переменная экземпляра @property имеет одно и то же имя, которое может сбивать с толку очень быстро. С собственностью foo вы не могли случайно сказать self._foo, которого нет. Существует self.foo и _foo. ваш пример recipe является Ивар и self.recipe это свойство. Очень легко один быстро запутать два при чтении кода.

Перед автоматическим синтезом, был промежуточный этап, на котором вы все еще нуждались в @synthesize, но ты для вас была создана переменная экземпляра backing. Эти новые функции помогают вам удалить шаблонный код.

Ответ автоответчика 1

Код, делающий то, что вам интересно, находится в tableView:cellForRowAtIndexPath. Здесь нет ничего волшебного. Когда вы выбрали новую категорию через TypeSelectionViewController, обновляется NSManagedObject. Назад в RecipeDetailViewController, cellForRowAtIndexPath вытаскивает прочную информацию из CoreData. text = [recipe.type valueForKey:@"name"];

Возможно, вы смущены тем, что такое @property. Это просто синтаксический сахар. В настоящее время A @property автоматически создает методы доступа и мутатора и поддерживающий ivar. Свойства сами по себе не являются областями для хранения данных, это просто быстрый способ создания некоторых методов и поддержки иваров.

Пример

@interface MyClass 
{ 
     NSUInteger _foo; 
} 

@end 

@implementation MyClass 

- (NSUInteger)foo 
{ 
     return (_foo) 
} 

- (void)setFoo:(NSUInteger)newFoo 
{ 
     _foo = newFoo; 
} 

@end 

эквивалентно:

@interface MyClass 
@property (nonatomic, assign) NSUInteger foo; 
@end 

Вы экономите много печатать. Когда вы попадаете в такие вещи, как NSString, свойства и различные модификаторы свойств, такие как strong или copy, количество кода, который вы сохраняете (и ошибок управления памятью, которых вы избегаете) в мутаторах становится намного больше.

+0

Не могли бы вы взглянуть на обновление – Pavan

+0

Обновлено.Вы должны открыть отдельный вопрос с новым заголовком, если вам нужна дополнительная помощь, чтобы другие могли прослушивать. – greg

+0

Привет, это правильно, хотя я не хотел тратить пространство, особенно если вопрос был так связан. Мой вопрос заключался в том, что присваивание 'recipe.type = [recipeTypes objectAtIndex: indexPath.row];' как-то обновляло cell.text контроллера родительского представления, чтобы выровнять пользователя, выбранного в childViewcontroller. Я не вижу нигде в этом втором блоке кода, где что-то сохраняется? : S – Pavan

0

Ваш .h файл должен быть вашим public api. Вы можете повторно объявить свои свойства в своем .m, файле реализации, который также считается private. Например

.h

@interface MyViewController : UITableViewController 
@property (readonly) NSString *name; 
@end 

.m

@implementation MyViewController 
@property (readwrite) NSString *name 
@end 

Здесь мы объявляем свойство публичного имени, которое readonly и в вашей реализации ты вновь объявляет свойство, так что вы может использовать аксессуар для установки.

+0

Свойства переопределяются в расширении класса, а не в реализации. –