то, что отличается от @implementation, добавить скобки и не добавлять скобки [duplicate]

Это должно сработать для вас:

$result = $data1." ".$data2;

Ссылка: Переменные строки PHP

74
задан TalkingCode 26 November 2012 в 22:25
поделиться

5 ответов

Возможность размещения переменных экземпляра в блоке @implementation или в расширении класса является функцией «современной среды выполнения Objective-C», которая используется каждой версией iOS и 64-разрядным Mac OS X.

Если вы хотите писать 32-разрядные приложения Mac OS X, вы должны поместить свои переменные экземпляра в объявление @interface. Скорее всего, вам не нужно поддерживать 32-разрядную версию вашего приложения. OS X поддерживает 64-разрядные приложения с версии 10.5 (Leopard), которая была выпущена более пяти лет назад.

Итак, предположим, вы только пишете приложения, которые будут использовать современную среду исполнения.

Вариант 0: В @interface (Do not Do It)

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

  1. Ввод переменных экземпляра в @interface предоставляет детали реализации для пользователей класса. Это может привести к тому, что пользователи (даже сами, используя собственные классы!) Будут полагаться на детали реализации, которых они не должны. (Это не зависит от того, объявляем ли мы ivars @private.)
  2. Помещение переменных экземпляра в @interface делает компиляцию более продолжительной, потому что, когда мы добавляем, изменяем или удаляем декларацию ivar, мы необходимо перекомпилировать каждый файл .m, который импортирует интерфейс.

Поэтому мы не хотим помещать переменные экземпляра в @interface.

Вариант 2: В @implementation без брекетов (Do not Do It)

Далее, давайте обсудим ваш вариант 2: «Положите iVars под @ воплощение без блока фигурных скобок ». Это не объявляет переменные экземпляра! Вы говорите об этом:

@implementation Person

int age;
NSString *name;

...

Этот код определяет две глобальные переменные. Он не объявляет никаких переменных экземпляра.

Хорошо определить глобальные переменные в вашем .m файле, даже в вашем @implementation, если вам нужны глобальные переменные - например, потому что вы хотите, чтобы все ваши экземпляры для совместного доступа к определенному состоянию, например кэш. Но вы не можете использовать эту опцию для объявления ivars, потому что она не объявляет ivars. (Кроме того, глобальные переменные, частные для вашей реализации, обычно должны быть объявлены static, чтобы избежать загрязнения глобального пространства имен и риска ошибок времени ссылки.)

Это оставляет ваши варианты 1 и 3.

Вариант 1: В @implementation с фигурными скобками (Do It)

Обычно мы хотим использовать опцию 1: поместите их в ваш основной блок @implementation в фигурных скобках, например:

@implementation Person {
    int age;
    NSString *name;
}

Мы помещаем их здесь, потому что они сохраняют свое существование частным образом, предотвращая проблемы, описанные мной ранее, и потому, что обычно нет причин помещать их в расширение класса.

Итак, когда мы хотите использовать свой вариант 3, помещая их в расширение класса?

Вариант 3: в расширении класса (делать это только при необходимости)

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

Но иногда мы могли бы написать класс, который достаточно велик, и мы хотим разделить его исходный код на несколько файлов. Мы можем сделать это с помощью категорий. Например, если бы мы реализовали UICollectionView (довольно большой класс), мы могли бы решить, что мы хотим поместить код, который управляет очередями многоразовых представлений (ячеек и дополнительных представлений) в отдельном исходном файле. Мы могли бы это сделать, разделив эти сообщения на категорию:

// UICollectionView.h

@interface UICollectionView : UIScrollView

- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
@property (nonatomic, retain) UICollectionView *collectionViewLayout;
// etc.

@end

@interface UICollectionView (ReusableViews)

- (void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;

- (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;

- (id)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath;
- (id)dequeueReusableSupplementaryViewOfKind:(NSString*)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath;

@end

OK, теперь мы можем реализовать основные UICollectionView методы в UICollectionView.m, и мы можем реализовать методы, которые управляют многоразовыми представлениями в UICollectionView+ReusableViews.m, что делает наш исходный код немного более управляемым.

Но нашему многоразовому коду управления представлением нужны некоторые переменные экземпляра. Эти переменные должны быть подвержены основному классу @implementation в UICollectionView.m, поэтому компилятор испустит их в файле .o. И нам также нужно подвергнуть эти переменные экземпляра коду в UICollectionView+ReusableViews.m, поэтому эти методы могут использовать ivars.

Здесь нам нужно расширение класса. Мы можем добавить ivars для многоразового просмотра в расширение класса в закрытом файле заголовка:

// UICollectionView_ReusableViewsSupport.h

@interface UICollectionView () {
    NSMutableDictionary *registeredCellSources;
    NSMutableDictionary *spareCellsByIdentifier;

    NSMutableDictionary *registeredSupplementaryViewSources;
    NSMutableDictionary *spareSupplementaryViewsByIdentifier;
}

- (void)initReusableViewSupport;

@end

Мы не будем отправлять этот заголовочный файл пользователям нашей библиотеки. Мы просто импортируем его в UICollectionView.m и в UICollectionView+ReusableViews.m, чтобы все, что нуждалось в , чтобы увидеть эти ивары, могут их видеть. Мы также выбрали метод, который мы хотим, чтобы основной метод init вызывал инициализацию кода управления повторного просмотра. Мы будем называть этот метод из -[UICollectionView initWithFrame:collectionViewLayout:] в UICollectionView.m, и мы его реализуем в UICollectionView+ReusableViews.m.

147
ответ дан rob mayoff 22 August 2018 в 09:01
поделиться
  • 1
    Вариант 3: также можно использовать, если: 1) вы хотите принудительно использовать свойства для ваших иваров, даже в пределах своей собственной реализации (время @property), и 2) вы хотите переопределить общедоступное свойство readonly (во-время (только для чтения)) в вашем заголовке, чтобы ваш код мог получить доступ к свойству как readwrite в реализации (@property (readwrite) int age). Если есть другие способы сделать это, @rob mayoff? – leanne 24 August 2013 в 23:13
  • 2
    @leanne Если вы хотите переопределить свойство readonly, чтобы в частном порядке быть readwrite, вам нужно использовать расширение класса. Но вопрос был о том, где поставить иваров, а не куда отправлять декларации собственности. Я не вижу, как использование расширения класса может препятствовать реализации доступа к ivars. Для этого вам нужно поместить реализации вашего метода в категорию, потому что компилятор должен увидеть все расширения класса ivar-объявления, прежде чем он увидит @implementation. – rob mayoff 24 August 2013 в 23:17
  • 3
    @rob mayoff, true и true - вы делаете действительные баллы. Холли указал, что свойства здесь не под вопросом, а «принудительное исполнение» был немного силен с моей стороны относительно их использования. Несмотря на это, если вы хотите использовать свойства для доступа к своим иварам, вместо того, чтобы делать это напрямую, тогда это будет способ сделать это. И, конечно же, вы можете получить доступ к ivars напрямую, используя «_», (_age = someAge). Я добавил комментарий, потому что я думал, что использование имущества стоит упомянуть при обсуждении ivars, так как многие люди используют их вместе, и это будет способ сделать это. – leanne 24 August 2013 в 23:56
  • 4
    @robmayoff, а как насчет этой опции ? – Iulian Onofrei 24 April 2015 в 10:01
  • 5
    Это «Вариант 0: на @interface (Do not Do It)». – rob mayoff 24 April 2015 в 12:38

Вариант 2 неверен. Это глобальные переменные, а не переменные экземпляра.

Варианты 1 и 3 по существу идентичны. Это не имеет никакого значения.

. Выбор заключается в том, следует ли поместить переменные экземпляра в файл заголовка или файл реализации. Преимущество использования файла заголовка в том, что у вас есть быстрый и простой комбинатор клавиш (Command + Control + Up в Xcode) для просмотра и редактирования ваших переменных экземпляра и декларации интерфейса.

Недостаток заключается в том, что вы открываете частные детали вашего класса в публичном заголовке. Это нежелательно в некоторых случаях, особенно если вы пишете код для других пользователей. Другая потенциальная проблема заключается в том, что если вы используете Objective-C ++, полезно избегать размещения каких-либо типов данных C ++ в вашем файле заголовка.

Переменные экземпляра реализации являются отличным вариантом для определенных ситуаций, но для большинства моих код Я все еще помещаю переменные экземпляра в заголовок просто потому, что это удобнее для меня как кодер, работающий в Xcode. Мой совет - делать то, что вы считаете более удобным для вас.

5
ответ дан Darren 22 August 2018 в 09:01
поделиться

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

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

4
ответ дан FluffulousChimp 22 August 2018 в 09:01
поделиться

Вы должны поместить переменные экземпляра в частный интерфейс выше реализации. Вариант 3.

Документация для чтения по этому вопросу - это Программирование в руководстве Objective-C .

Из документации:

Вы можете определить переменные экземпляра без свойств

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

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

3
ответ дан JoePasq 22 August 2018 в 09:01
поделиться
  • 1
    Я согласен с вами: если вы собираетесь определить ivar, расширение частного класса - лучшее место. Любопытно, однако, что документация, на которую вы ссылаетесь, не только не имеет места, где должны быть определены ивары (она просто излагает все три альтернативы), но она идет дальше и рекомендует не использовать иваров вообще, но скорее «лучше использовать свойство». Это лучший совет, который я видел до сих пор. – Rob 29 May 2016 в 04:29

Публичные ivars действительно должны быть объявлены свойствами в @interface (вероятно, о чем вы думаете в 1). Частные ивары, если вы используете новейший Xcode и используете современную среду выполнения (64-разрядную ОС X или iOS), могут быть объявлены в @implementation (2), а не в расширении класса, что, скорее всего, размышляя о 3.

1
ответ дан Jon Shier 22 August 2018 в 09:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: