переменная экземпляра / именование аргумента метода в Objective C

Если вы хотите проверить наличие abc в любой строке в списке, вы можете попробовать

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in some_list):
    # whatever

Если вы действительно хотите получить все элементы, содержащие abc, использовать

matching = [s for s in some_list if "abc" in s]
15
задан philsquared 17 February 2009 в 18:07
поделиться

5 ответов

Как Вы отметили, стиль Какао должен использовать имена аргумента метода как theValue, если имя аргумента будет конфликтовать с переменной экземпляра. Не должен много раз быть, что это подходит в Objective C 2,0 кода стиля, как бы то ни было. Предположение - то, что Вы не должны (обычно) получать доступ к переменным экземпляра непосредственно. Главным образом это вызвано тем, что выполнение так обходит оборудование для Наблюдения Значения ключа в Какао. Скорее ожидание состоит в том, что Вы получите доступ и видоизмените свойства через метод считывания/методы установщика. В Objective C 2.0, легко объявить эти свойства и автоматически @synthesize методы считывания/методы set, таким образом, нет большого оправдания за то, что не использовались они. На самом деле, в 64-разрядных системах, время выполнения автоматически создаст переменные экземпляра для Вас, устраняя потребность объявить их и уменьшая желание использовать их.

единственное время необходимо получать доступ к переменным экземпляра, непосредственно находится в -init и -dealloc методы:

@interface MyObject : NSObject 
{
  id ivar;
}

@property (retain,readwrite) id ivar; //or whatever retain/copy/assign and read/readwrite makes sense
@end

@implementation MyObject
@synthesize ivar;

- (id)initWithIvar:(id)theIvar {
  if(self = [super init]) {
    ivar = theIvar;
  }

  return self;
}

- (void)dealloc {
  [ivar release];
}

причина ivar должен использоваться непосредственно в этих случаях, то, потому что метод считывания/метод set может иметь побочные эффекты, которые зависят от полностью инициализированного экземпляра, таким образом делая их опасными в -init и -dealloc, где состояние объекта полностью инициализируется. Во всех других случаях необходимо использовать self.ivar (или [self ivar] и [self setIvar:newValue]).

казалось бы, что методы кроме [1 110] не должны иметь конфликта имен. Если они делают, разве они не должны быть пересмотрены, чтобы не иметь тот параметр или чтобы Класс не имел переменную экземпляра?

Это уезжает просто -initWithXX методы, где Вы часто находили бы конфликт между аргументами и ivars. Для этого случая можно использовать любой из подходов, которые Вы упоминаете, не можете ли Вы действительно выдержать стиль Какао. Добавление префикса [1 112] работы и относительно распространены (я верю @synthesize 'd методы set, и методы считывания автоматически сделают правильную вещь в этом случае, но Вам, вероятно, придется явно установить _ivar как поддержка).

17
ответ дан 1 December 2019 в 03:24
поделиться

Завершать весь известный Objective C styleguides здесь - версия Google. Что они делают должно добавить подчеркивание после участник varname. Например BOOL isActive_;.
Так делают выбор и придерживаются его. Я также предпочитаю "_" префикс для моих приложений.

2
ответ дан 1 December 2019 в 03:24
поделиться

Пример кода, произведенный Apple обычно, использует "_" префикс. Я думаю, что также видел некоторое использование mFoo или m_foo. Некоторые не беспокоятся префиксами вообще и просто используют нормальное имя, однако который становится сбивающим с толку позже. В целом при определении параметров метода, соглашение о присвоении имен состоит в том, чтобы использовать "a", или "новый" префикс. Например:

@interface Foo : NSObject {
    id _bar;
}
@property (nonatomic, retain) id bar;

- (id) initWithBar:(id)aBar;

@end

@implementation Foo
@synthesize bar = _bar;

- (id) initWithBar:(id)aBar {
    self = [super init];
    if(self != nil) {
        _bar = aBar;
    }
    return self;
}

@end

я нахожу, что эта конвенция работает вполне хорошо. Я раньше не беспокоился префиксом, но это сделало вещи, путающие иногда. Используя префикс ясно указывает, что это - переменная экземпляра. @synthesize bar = _bar конвенция используется Apple в их (iPhone) пример кода.

переменная экземпляра обычно не использовалась бы так или иначе, поэтому если бы Вы находите "_" префикс раздражающий, это не имеет значения, потому что Вы использовали бы [self bar] (или self.bar, если Вы в такую вещь), так или иначе.

1
ответ дан 1 December 2019 в 03:24
поделиться

Вот то, как Apple делает это .

1
ответ дан 1 December 2019 в 03:24
поделиться

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

Вы также можете получить доступ к переменным в Obj-C через self. Итак, если у вас есть тест переменной экземпляра, вы можете получить к нему доступ через само-> тест, это законно и всегда будет работать. Однако это не красиво в глазах большинства программистов Obj-C. Он раскрывает «секрет», что объекты на самом деле являются просто структурами (точнее, ссылки на объекты - это указатели на структуры), а переменные экземпляра фактически являются членами структуры. Не то чтобы это действительно секрет, но программисты Obj-C, кажется, предпочитают «скрывать» этот факт в своем коде.

Использование символа подчеркивания «_» в имени - очень плохая идея. Кто-то здесь указал, что Apple резервирует подчеркивание для своего кода, но на самом деле GCC уже резервирует подчеркивание для имен символов. Точнее, уже стандарт ANSI-C говорит, что переменные, начинающиеся либо с двух подчеркиваний, либо с одного подчеркивания и буквы верхнего регистра, зарезервированы для внутреннего использования компилятором. Таким образом, использование одного подчеркивания теоретически допустимо, но если случайно начать имя с заглавной буквы, оно становится недействительным.

До сих пор я пытался использовать префикс my, myName вместо имени и использовать префикс self, selfName вместо имени; Поначалу оба выглядят как-то странно, но в огромном фрагменте кода выглядят неплохо. По крайней мере, сразу бросается в глаза как «другой». Я также просто пробовал использовать один «i», iName вместо имени (или iname вместо имени), но я был не очень доволен этим решением.

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

- (NSImage *)loadImage:(int)imageNumber
{
  NSImage * res;

  // Some code that assigns a value to res
  // ...  

  // Re-use imageNumber for a different purpose
  for (imageNumber = 0; ...; ...) {
     // Some code
  }

  return res;
}

Я не вижу проблем с этим кодом. Зачем мне объявлять для этого вторую переменную стека, если имя все еще имеет смысл (если я не перебираю изображения по номеру в цикле for, имя, конечно, не имеет смысла, в этом случае я бы использовал другая переменная для этого - компилятор может фактически зарезервировать только один int в стеке для обоих).

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

- (NSImage *)loadImage:(int)imageNumber
{
  NSImage * res;

  // Some code that assigns a value to res
  // ...  

  // Re-use imageNumber for a different purpose
  for (imageNumber = 0; ...; ...) {
     // Some code
  }

  return res;
}

Я не вижу проблем с этим кодом. Зачем мне объявлять для этого вторую переменную стека, если имя все еще имеет смысл (если я не перебираю изображения по номеру в цикле for, имя, конечно, не имеет смысла, в этом случае я бы использовал другая переменная для этого - компилятор может фактически зарезервировать только один int в стеке для обоих).

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

- (NSImage *)loadImage:(int)imageNumber
{
  NSImage * res;

  // Some code that assigns a value to res
  // ...  

  // Re-use imageNumber for a different purpose
  for (imageNumber = 0; ...; ...) {
     // Some code
  }

  return res;
}

Я не вижу проблем с этим кодом. Зачем мне объявлять для этого вторую переменную стека, если имя все еще имеет смысл (если я не перебираю изображения по номеру в цикле for, имя, конечно, не имеет смысла, в этом случае я бы использовал другая переменная для него - компилятор может фактически зарезервировать только один int в стеке для обоих).

1
ответ дан 1 December 2019 в 03:24
поделиться
Другие вопросы по тегам:

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