Objective-C: простой вопрос о объявлениях заголовочных файлов - PullRequest
3 голосов
/ 31 августа 2011

Здесь новичок, занимающийся разработкой для iPhone, с чрезвычайно простым вопросом: в чем причина объявления метода в заголовочном файле и последующего его заполнения в файле реализации?Это всегда нужно делать?

Кроме того, я знаю, как объявлять переменные в @interface заголовочного файла, но почему они только иногда повторяются стег @property?Это для переменных, из которых другие классы могут захотеть читать или записывать (поэтому они автоматически создают методы получения и установки)?

С уважением.

Ответы [ 5 ]

10 голосов
/ 31 августа 2011

Объявление метода в файле .h называется предварительным объявлением. Если вы объявите заголовок метода в файле .h, то компилятор будет знать имя метода, параметры и тип возвращаемого значения до фактического связывания. Вы можете написать тело метода только в .m файле. Но этот метод может использоваться только методами, объявленными после него в этом файле. Но если вы объявите метод в заголовке, это не будет иметь значения. Потому что тогда сигнатура метода будет известна всем во время первого прохода компилятора и будет связана во втором проходе.

Теги

@property и @synthesize используются для создания автоматических методов получения и установки (или Accessors и Mutators, в терминологии Objective-C), но это еще не все. В iOS вы должны выполнять управление памятью вручную (оно должно быть изменено в iOS5, как и обещал Apple). В теге @property вы можете указать, как память будет вести себя во время назначения.

iOS отслеживает управление памятью объекта, поддерживая счет сохранения. Когда вы выделяете объект, его счетчик хранения становится равным 1. Затем вы можете вручную увеличить счетчик хранения с помощью метода сохранения (например, [myObj retain]) или уменьшить счет сохранения с помощью метода деблокирования (например, [myObj release]). Когда счетчик сохранится до 0 iOS, удалите этот объект из памяти. С помощью тега @property вы можете определить, как будет удерживаться счет во время назначения. Например, два наиболее часто используемых параметра в теге @property:

@property (nonatomic, retain)
@property (nonatomic, assign)

В первом случае во время назначения счет сохранения объекта будет автоматически увеличен на 1 (например, self.myObj = anotherClass.anotherObjOfSameClass;), а в последнем случае счет сохранения не будет увеличен.

4 голосов
/ 31 августа 2011

Смысл заголовочного файла на любом языке Си состоит в том, чтобы отделить реализацию от доступных методов.То есть вы определяете шаблон класса в заголовочном файле, так что кто-то, использующий ваш код, может просто сказать: «О, хорошо, я хочу использовать этот и этот метод, и теперь я знаю, как создать объект этого класса».Все дело в абстракции.: -)

3 голосов
/ 31 августа 2011

Полагаю, это просто сделать два файла, один для публичного API (.h) и вашу логику и реализацию в (.m), чтобы скрыть их от других людей.Кроме того, тег свойства помогает создавать геттеры и сеттеры для вашей переменной.

вы используете @property в заголовочном файле, а затем @synthesize его в реализации, что позволит вам получить доступ через геттеры и сеттеры.читая дальше,

http://developer.apple.com/library/mac/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/_index.html#//apple_ref/doc/uid/TP40007594

К вашему сведению, вы тоже можете сделать что-то подобное, Но не рекомендуется

#import <UIKit/UIKit.h>

@interface FileSystemDemoViewController : UIViewController {

    UITextView *actorListBox;
    NSArray *dataToShow;
}

@property (nonatomic, retain) IBOutlet UITextView *actorListBox;
@property (nonatomic, retain) NSArray *dataToShow;

-(IBAction) covertToAscending:(id)sender;
-(IBAction) covertToDescending:(id)sender;

@end

@implementation
...Your implementation here...
@end

Выше всего код находится в.m файл, реализация.

снова НЕ РЕКОМЕНДУЕТСЯ

Счастливое кодирование

2 голосов
/ 31 августа 2011

Зачем разделять файлы .h и .m?

Исторически в C, когда вы включали файл .h, это было почти буквально эквивалентно вставке файла в файл, который его включал. По сути, все ваши объявления повторялись в каждом файле, который их использовал. Это нормально, в C вы можете повторять объявления сколько хотите, если они не меняются. Однако повторяющиеся определения приведут к множественным копиям функции и общей поломке. Поэтому вы не можете включить весь код модуля, только его объявления.

Я думаю, что Objective-C на самом деле умнее, и вы можете, если хотите, вообще не иметь файлов .m и поместить весь код в файлы .h. Вы также можете определить класс только в .m-файле и не иметь .h-файла, но вы не можете создать такой проект целиком, поскольку ничто не сможет получить доступ к чему-либо еще.

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

Почему некоторые переменные экземпляра имеют свойства, а некоторые нет?

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

Еще одна вещь, которую вы получаете со свойствами - это автоматическое управление памятью. Если вы используете атрибут сохранения, то при назначении значения свойству количество сохраняемых значений увеличивается, а количество сохраняемых значений предыдущего значения (если оно есть) уменьшается. Это очень удобно и позволяет избежать глупостей. Даже если другие классы не обращаются к переменной экземпляра, это полезно. Если вы не используете свойства, вы должны убедиться, что вы выполняете соответствующие инструкции сохранения и выпуска в своих методах экземпляра, чтобы избежать утечки памяти. Есть и другие автоматические варианты поведения, которые вы можете использовать для свойств, например блокировка или копирование.

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

1 голос
/ 31 августа 2011

Как уже отмечалось, первоначальная причина для файлов .h и .m заключается в том, что компиляторы C обрабатывают каждый исходный файл изолированно, а затем соединяют точки между ними только тогда, когда они приходят к ссылке.Следовательно, должен существовать некоторый механизм, с помощью которого объявления могут распространяться - чтобы каждый файл мог отдельно проверяться на наличие ошибок и предупреждений компилятора - но определения остаются в одном месте - чтобы компоновщик мог гарантировать, что общие ресурсы оказались в общем месте.

В современной среде выполнения различие между файлами .h и .m лучше воспринимается как различие между интерфейсом и реализацией.Интерфейс - это то, что вы публикуете для всеобщего обозрения.Реализация это то, что только для знания этого класса.Ваш единственный контракт с внешним миром - это тот, который определяется интерфейсом.

Objective-C, как и большинство объектно-ориентированных языков, принимает концепцию методов получения и установки для свойств объекта.Объекты не имеют доступа к переменной экземпляра других объектов, вместо этого они спрашивают "что это за значение?"или «пожалуйста, установите значение этого».До Objective-C 2.0 вам приходилось писать геттеры и сеттеры самостоятельно, что вводило много повторяющихся шаблонов кода.Первоначальная цель @property состояла в том, чтобы объявить получатели или установщики в интерфейсе.@synthesize используется для генерации реализации по умолчанию для чего-то, объявленного как @property.

Начиная с новой среды выполнения, нет необходимости объявлять переменные экземпляра в интерфейсе, вы можете полностью сохранить их в реализации,Так, например:

SomeClass.h:

@interface SomeClass: NSObject

- (void)doSomeTask;

@end

SomeClass.m:

// declare a category with some unexposed properties
@interface SomeClass ()
@property (nonatomic, assign) NSMutableArray *arrayForMe;
@end

@implementation SomeClass

@synthesize arrayForMe; // you can now use the property self.arrayForMe,
                        // even though you didn't declare a backing
                        // instance variable

- (void)doSomePrecursorTask
{
    // ...
}

- (void)doSomeTask
{
    // as a fact of implementation, I need to do something else
    // first. Because it's an implementation specific, I don't
    // want to put it in the declared interface

    [self doSomePrecursorTask];
    // ...
}

@end

Новая среда выполнения доступна на iOS, Lion и 64-битном Snow Leopard,В соответствии с хорошей практикой, вероятно, теперь имеет смысл не указывать переменные экземпляра в заголовочных файлах.Просто поместите общедоступный интерфейс и думайте о них как о способе формализации и общения.Я ожидаю, что переменные экземпляра в заголовке будут выглядеть так же старомодно, как NSEnumerator очень быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...