С тех пор, как я начал работать над приложениями для iOS и с целью C, я был озадачен тем, что в разных местах можно объявлять и определять переменные. С одной стороны, у нас есть традиционный подход C, с другой - новые директивы ObjectiveC, которые добавляют объектно-ориентированный подход к этому. Не могли бы вы, ребята, помочь мне понять лучшие практики и ситуации, в которых я хотел бы использовать эти местоположения для своих переменных и, возможно, исправить мое нынешнее понимание?
Вот образец класса (.h и .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
@interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
@end
и
#import "SampleClass.h"
// 4) what goes here?
@interface SampleClass()
// 5) private interface, can define private methods and properties here
@end
@implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
@end
- Насколько я понимаю, пункты 1 и 4 состоят в том, что это декларации и определения на основе файлов в стиле C, которые не имеют никакого представления о концепции класса и, следовательно, должны использоваться именно так, как они будут использоваться в C. Я видел их ранее использовался для реализации статических синглтонов на основе переменных. Есть ли другие удобные способы использования, которые мне не хватает?
- Мой вывод из работы с iOS заключается в том, что ivars были полностью отменены за пределами директивы @synthesize и, таким образом, могут в основном игнорироваться. Так ли это?
- По поводу 5: зачем мне вообще объявлять методы в частных интерфейсах? Мои методы частного класса отлично компилируются без объявления в интерфейсе. Это в основном для удобства чтения?
Спасибо большое, ребята!
источник
Сначала прочтите ответ @DrummerB. Это хороший обзор того, почему и что вам следует делать. Имея это в виду, к вашим конкретным вопросам:
Здесь нет фактических определений переменных (это технически законно, если вы точно знаете, что делаете, но никогда не делайте этого). Вы можете определить несколько других типов вещей:
Экстерны выглядят как объявления переменных, но это просто обещание объявить их где-то еще. В ObjC их следует использовать только для объявления констант и, как правило, только строковых констант. Например:
Затем вы должны в своем
.m
файле объявить фактическую константу:Как отмечает DrummerB, это наследие. Не кладите сюда ничего.
Ага.
Внешние константы, как описано выше. Также сюда могут быть помещены статические переменные файла. Это эквивалент переменных класса в других языках.
Ага
Но очень редко. Почти всегда вы должны позволять clang (Xcode) создавать переменные за вас. Исключения обычно связаны с ivars, не относящимися к ObjC (например, с объектами Core Foundation и особенно с объектами C ++, если это класс ObjC ++), или с ivars, которые имеют странную семантику хранения (например, ivars, которые по какой-то причине не соответствуют свойству).
Как правило, вы больше не должны использовать @synthesize. Clang (Xcode) сделает это за вас, и вы должны позволить.
За последние несколько лет все стало намного проще. Побочным эффектом является то, что теперь существует три разных эпохи (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). Поэтому, когда вы видите старый код, это может немного сбить с толку. Таким образом, путаница возникает из-за простоты: D
источник
Я тоже новенький, так что, надеюсь, я ничего не напортачил.
1 и 4: Глобальные переменные в стиле C: они имеют файловую область видимости. Разница между ними в том, что, поскольку они имеют размер файла, первый будет доступен любому, кто импортирует заголовок, а второй - нет.
2: переменные экземпляра. Большинство переменных экземпляра синтезируются и извлекаются / устанавливаются с помощью средств доступа с использованием свойств, поскольку это делает управление памятью приятным и простым, а также дает вам легкую для понимания точечную нотацию.
6: ivars реализации несколько новы. Это хорошее место для размещения частных ivars, поскольку вы хотите отображать только то, что необходимо в общедоступном заголовке, но подклассы не наследуют их AFAIK.
3 и 7: объявления открытых методов и свойств, затем их реализации.
5: Частный интерфейс. Я всегда использую частные интерфейсы, когда могу, чтобы поддерживать чистоту и создавать своего рода эффект черного ящика. Если им не нужно об этом знать, напишите об этом. Тоже делаю для читабельности, не знаю, есть ли другие причины.
источник
Это пример всех видов переменных, объявленных в Objective-C. Имя переменной указывает на ее доступ.
Файл: Animal.h
Файл: Animal.m
Обратите внимание, что переменные iNotVisible не видны из других классов. Это проблема видимости, поэтому объявление их с
@property
или@public
не меняет.Внутри конструктора рекомендуется обращаться к переменным, объявленным с
@property
использованием подчеркивания,self
чтобы избежать побочных эффектов.Попробуем получить доступ к переменным.
Файл: Cow.h
Файл: Cow.m
Мы все еще можем получить доступ к невидимым переменным, используя среду выполнения.
Файл: Cow.m (часть 2)
Попробуем получить доступ к невидимым переменным.
Файл: main.m
Это печатает
Обратите внимание, что мне удалось получить доступ к резервному ivar,
_iNotVisible2
который является частным для подкласса. В Objective-C можно читать или устанавливать все переменные, даже отмеченные@private
, без исключений.Я не включил связанные объекты или переменные C, так как это разные птицы. Что касается переменных C, любая переменная определена вне
@interface X{}
или@implementation X{}
является переменной C с областью файла и статическим хранилищем.Я не обсуждал атрибуты управления памятью или атрибуты только для чтения / чтения / записи, получения и установки.
источник