Как вы называете значения экземпляра/параметра?

StackOverflow https://stackoverflow.com/questions/10314

  •  08-06-2019
  •  | 
  •  

Вопрос

Будучи новичком в Objective-C (но давним программистом на C/++), я ищу советы/рекомендации по соглашениям об именах для переменных.

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

Итак, учитывая приведенный ниже код, какой стиль именования для переменных экземпляра/функции вы предпочитаете?И если вас не затруднит, как вы справляетесь с затенением параметров функции?

@interface GridItem : NSObject
{
    CGRect _rect;
    ...  
}
@end

-(void) initFromRect:(CGRect)rect
{
    _rect = rect;
    ...
}

Ваше здоровье!

Это было полезно?

Решение

Большинство проектов Cocoa используют нижнюю полосу как необязательный элемент.IBOutlet префикс переменной экземпляра и не используйте префикс для IBOutlet переменные экземпляра.

Причина, по которой я не использую подчеркивания IBOutlet Переменные экземпляра заключаются в том, что при загрузке файла пера, если у вас есть метод установки для подключенной розетки, этот метод установки будет вызываться. Однако этот механизм делает нет используйте кодирование «ключ-значение», поэтому IBOutlet, имя которого начинается с подчеркивания (например _myField) воля нет быть установлен, если установщик не назван точно так же, как выход (например set_myField:), что является нестандартным и брутто.

Также имейте в виду, что использование таких свойств, как self.myProp является нет то же самое, что и доступ к переменным экземпляра.Ты отправка сообщения когда вы используете свойство, точно так же, как если бы вы использовали обозначение скобок, например [self myProp].Все, что делают свойства, — это дают вам краткий синтаксис для указания как геттера, так и сеттера в одной строке, и позволяют синтезировать их реализацию;на самом деле они не замыкают механизм отправки сообщений.Если вы хотите напрямую получить доступ к переменной экземпляра, но присвоить ей префикс self тебе нужно лечить self как указатель, например self->myProp что на самом деле является доступом к полю в стиле C.

Наконец, никогда не используйте венгерскую нотацию при написании кода Cocoa и избегайте других префиксов, таких как «f» и «m_» — они будут отмечать код как написанный кем-то, кто «не понимает», и это приведет к тому, что он будет может вызвать подозрение у других разработчиков Cocoa.

В общем, следуйте советам в Рекомендации по кодированию для какао документ на Связь с разработчиками Apple, и другие разработчики смогут уловить и понять ваш код, и ваш код будет хорошо работать со всеми функциями Cocoa, использующими самоанализ во время выполнения.

Вот как может выглядеть класс оконного контроллера, если использовать мои соглашения:

// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    IBOutlet NSTextField *nameField;
    IBOutlet NSTextField *titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;

@end

// EmployeeWindowController.m
#import "EmployeeWindowController.h"

@implementation EmployeeWindowController

@synthesize employee = _employee;

- (id)initWithEmployee:(Employee *)employee {
    if (self = [super initWithWindowNibName:@"Employee"]) {
        _employee = [employee retain];
    }
    return self;
}

- (void)dealloc {
    [_employee release];

    [super dealloc];
}

- (void)windowDidLoad {
    // populates the window's controls, not necessary if using bindings
    [nameField setStringValue:self.employee.name];
    [titleField setStringValue:self.employee.title];
}

@end

Вы увидите, что я использую переменную экземпляра, которая ссылается на Employee прямо в моем -init и -dealloc метод, в то время как я использую это свойство в других методах.Обычно это хороший шаблон со свойствами:Прикасайтесь только к базовой переменной экземпляра свойства в инициализаторах, в -dealloc, а также в методах получения и установки свойства.

Другие советы

Я следую совету Криса Хэнсона относительно префикса подчеркивания ivar, хотя признаю, что использую подчеркивание и для IBOutlets.Однако недавно я начал перемещать свой IBOutlet заявления для @property линия, согласно предложение @mmalc.Преимущество в том, что все мои ivar теперь имеют подчеркивание и вызываются стандартные установщики KVC (т. setNameField:).Кроме того, имена торговых точек не имеют подчеркивания в Интерфейсном Разработчике.

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    NSTextField *_nameField;
    NSTextField *_titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;
@property(nonatomic, retain) IBOutlet NSTextField *nameField;
@property(nonatomic, retain) IBOutlet NSTextField *titleField;

@end

Вы можете использовать префикс подчеркивания в своих ivars и по-прежнему использовать имя без подчеркивания для своих свойств.Для синтезированных средств доступа просто сделайте следующее:

@synthesize foo = _foo;

Это указывает компилятору синтезировать свойство foo, используя ivar_foo.

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

Лично я следую соглашениям об именах Cocoa, используя верблюжий регистр для функций и переменных и записывая верблюжьи буквы для имен объектов (конечно, без начального NS).

Я считаю, что префиксы типов делают код более непрозрачным для тех, кто его не писал (поскольку все неизменно используют разные префиксы), а в современной IDE не так уж и сложно определить тип чего-либо.

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

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

Я думаю, что использовать «self.variable» некрасиво.

Обычно я использую простые идентификаторы (то есть без префиксов и суффиксов) для переменных экземпляра.Если ваш класс настолько сложен, что вы не можете запомнить переменные экземпляра, у вас проблемы.Итак, для вашего примера я бы использовал «rect» в качестве имени переменной экземпляра и «newRect» или «aRect» в качестве имени параметра.

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

Префиксы переменных экземпляра всегда казались мне стилем C++, который был перенесен в Java, а затем и в C#.Поскольку мир Objective-C во многом был параллелен миру C++, а миры Java и C# являются его преемниками, это объясняет «культурную» разницу, которую вы можете увидеть в этом между разными группами разработчиков.

Мой стиль гибридный и на самом деле пережиток времен PowerPlant:

Наиболее полезные префиксы, которые я использую, — это «in» и «out» для параметров функции/метода.Это поможет вам сразу понять, для чего нужны параметры, и действительно помогает предотвратить конфликты между параметрами метода и переменными экземпляра (сколько раз вы видели конфликт параметра «таблица» с переменной экземпляра с тем же именем).Например.:

- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;

Затем я использую чистое имя для переменных экземпляра и имен свойств:

Затем я использую «the» в качестве префикса для локальных переменных:theTable, theURL и т. д.Опять же, это помогает различать локальные переменные и переменные экземпляра.

Затем, следуя стилю PowerPlant, я использую несколько других префиксов:k для констант, E для перечислений, g для глобальных переменных и s для статики.

Я использую этот стиль уже около 12 лет.

Хотя мне нравится использовать префикс подчеркивания для иваров, я ненавижу писать @synthesize строк из-за всего дублирования (это не очень СУХОЙ).Я создал макрос, который поможет сделать это и уменьшить дублирование кода.Таким образом, вместо:

@synthesize employee = _employee;

Я пишу это:

ddsynthesize(employee);

Это простой макрос, использующий вставку токенов для добавления подчеркивания справа:

#define ddsynthesize(_X_) @synthesize _X_ = _##_X_

Единственным недостатком является то, что это запутает инструмент рефакторинга Xcode и не будет переименовано, если вы переименуете свойство путем рефакторинга.

Помимо того, что было сказано здесь, обязательно прочитайте документацию Cocoa по именованию, совместимому с Key Value Observing.Строгое следование этому шаблону очень поможет вам в долгосрочной перспективе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top