Шаблон iOS-файла Apple с основными данными и представлениями таблиц - PullRequest
1 голос
/ 04 июля 2011

Я понимаю, что делает основной синтез в объективе C, но я не понимаю, что Apple делает здесь. Это отображается в RootViewController шаблона проекта с основными данными и табличными представлениями.

@synthesize managedObjectContext=__managedObjectContext;

Какова цель «__» и что вы делаете, когда вы синтезируете объект и устанавливаете равный другому объекту, который не используется где-либо еще в контроллере представления, хотя он используется в делегате приложения?

Я также заметил, что __managedObjectContext высвобождается в методе dealloc, но не ManagerObjectContext.

Ответы [ 4 ]

0 голосов
/ 05 июля 2011

Свойства в Objective-C 2.0 - это не объекты, а методы.

Вернувшись в Objective-C 1.0, вы должны были создать свои собственные средства доступа, например:

@interface RootViewController : UITableViewController  {
  NSManagedObjectContext *__managedObjectContext;
}
@end

@implementation RootViewController

-(NSManagedObjectContext *) managedObjectContext{
  if (__managedObjectContext!=nil) {
    return __managedObjectContext;
  }

  //... else initialize the context
  [__managedObjectContext retain];
  return __managedObjectContext;
}

-(void) setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{
  if (__managedObjectContext!=nil) {
    [__managedObjectContext release];
    __managedObjectContext=nil;
  }
  __managedObjectContext=managedObjectContext;
  [__managedObjectContext retain];
}

Вы бы использовали это так:

NSManagedObjectContext *moc=[self managedObjectContext];

или

[self setManagedObjectContext:anotherContext];

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

В Objective-C 2.0 объединенные директивы @property и @synthesize автоматизируют все это свойство.

Объявление свойства сообщает прекомпилятору, какие методы создавать по имени, readwrite, атомарности, сохранению и т. Д. Директива synthes сообщает прекомпилятору, какие методы свойств нужно генерировать автоматически, если они не существуют. По умолчанию он также создает переменную экземпляра с тем же именем, что и у свойства. Если вы добавите = someOtherSymbol, он создаст переменную экземпляра с другим именем, чтобы вы случайно не обратились к нему.

Нотация собственной точки автоматически вызывает метод средства доступа вместо прямого доступа к переменной экземпляра. Это важно, потому что если вы сделаете это:

__managedObjectContext= aContext;

... недавно переданный объект aContext не сохраняется и не освобождается и может либо неожиданно исчезнуть, либо утечь память. Это связано с тем, что прямая ссылка не вызывает метод доступа, тогда как:

self.manageObjectContext= aContext;

или [self setManagedObjectContext: aContext];

и методы доступа к вызову, и автоматическая обработка удержания.

0 голосов
/ 04 июля 2011

Причина состоит в том, чтобы защитить программиста от самого себя. Оборонительное программирование. Бывают случаи, когда вы хотите получить доступ к значению через метод доступа (self.managedObjectContext), а в другие - эффективный доступ к переменной экземпляра напрямую (__managedObjectContext).

Это более общая проблема, не связанная с CoreData или контекстами управляемого объекта. Без части = __managedObjectContext переменная экземпляра и ее метод доступа имели бы одно и то же имя. Это не редкость, когда кто-то пишет managedObjectContext = foo;, который отказывается от средства доступа и необходимого retain. С изменением имени переменной вы, ваше будущее я и другие читатели кода, скорее всего, заметите что-то проблематичное, например __managedObjectContext = foo;

Я часто буду сокращать имена внутри класса, используя что-то вроде @synthesize managedObjectContext=_moc; в качестве личного предпочтения - удерживая часть моего кода от переноса из-за длинных имен. Но подробный и понятный интерфейс поддерживается.

0 голосов
/ 04 июля 2011

Предположим, у вас есть этот кусок кода:

@interface A {
    Foo *_foo;
}
@property(nonatomic, retain) Foo *foo;

@end


@implementation A 

@synthesize foo = _foo;

// ...

- (void)dealloc {
    [_foo release];
    [super dealloc];
}

@end 

В этом случае начальное подчеркивание ("_") - это соглашение , способ различать имяпеременная экземпляра (iVar) и имя свойства.Это означает, что у вас есть соглашение о кодировании, позволяющее различать доступ к свойству (через средства доступа) и прямой доступ (через указатель).

Также обратите внимание, что в @synthesize foo = _foo; никакого присвоения значения не производится.Это просто означает, что синтезированные средства доступа должны использовать iVar с именем _foo для хранения.

И наконец, поскольку _foo - это имя вашего iVar, вы должны написать [_foo release].Выпускается именно iVar, а не собственность (видите различие?).

Надеюсь, это поможет ...

0 голосов
/ 04 июля 2011

Это не другой объект.Это указывает имя переменной экземпляра, которая поддерживает свойство.Для получения дополнительной информации см. Объявленные свойства .

...