이 포스트는 Apple Documentation Archive 중 Coding Guidelines for Cocoa 정리한 포스트입니다.
Introduction to Coding Guidelines for Cocoa
공개 API를 사용하여 Cocoa 프레임 워크, 플러그인 또는 기타 실행 파일을 개발하려면 애플리케이션 개발에 사용 된 것과 다른 접근 방식 및 규칙이 필요합니다. 제품의 주요 클라이언트는 개발자이며 프로그래밍 인터페이스에 의해 미스터리되지 않는 것이 중요합니다.
General Principles
Clarity (명확성)
가능한 한 명확하고 간략하게 하는 것이 좋지만, 간결함으로 인해 명확성이 손상되지 않아야 합니다.
Code | Commentary |
insertObject:atIndex: | ✅ |
insert:at: |
❌ 무엇이 삽입되는지? at 은 무엇을 의미하는지? (what is being inserted? what does “at” signify?) |
removeObjectAtIndex: |
✅Argument에 참조된 객체를 제거하기 때문에 좋습니다. (because it removes object referred to in argument.) |
remove: |
❌무엇이 제거됩니까? (what is being removed?) |
이름을 축약하지 마십시오.
Code | Commentary |
destinationSelection | ✅ |
destSel | ❌ 명확하지 않다 |
setBackgroundColor: | ✅ |
setBkgdColor: | ❌ 명확하지 않다 |
여러 가지 방법으로 해석 될 수있는 메소드 이름과 같은 API 이름의 모호성을 피하십시오
Code | Commentary |
sendPort |
❌port 를 보내거나 반환합니까? (Does it send the port or return it?) |
displayName |
❌Display 를 표시하거나 Display를 반환합니까? (Does it display a name or return the receiver’s title in the user interface?) |
Consistency (일관성)
Cocoa 프로그램 인터페이스 전체에서 일관되게 이름을 사용하십시오.
일관성은 메소드가 다형성을 사용해야하는 클래스가 있을 때 특히 중요합니다.
Code | Commentary |
- (NSInteger)tag |
NSView, NSCell, NSControl에 정의되어 있습니다. (Defined in NSView, NSCell, NSControl.) |
- (void)setStringValue:(NSString *) |
많은 Cocoa 클래스에서 정의됩니다. (Defined in a number of Cocoa classes.) |
No Self Reference (자기 참조 없음)
이름은 자기 참조가되어서는 안됩니다
Code | Commentary |
NSString |
✅ |
NSStringObject |
❌ 자기 참조 |
비트 연산으로 결합 될 수 있는 마스크의 상수는 알림 이름의 상수와 마찬가지로이 규칙에서 예외입니다.
Code | Commentary |
NSStringNSUnderlineByWordMask |
✅ |
NSTableViewColumnDidMoveNotification |
✅ |
Prefixes
접두사는 프로그래밍 인터페이스에서 이름의 중요한 부분입니다. 소프트웨어의 기능 영역을 차별화합니다.
접두사는 타사 개발자가 정의한 기호와 Apple이 정의한 기호 (Apple 자체 프레임 워크의 기호) 간의 충돌을 방지합니다
Code | Commentary |
NS |
Foundation |
NS |
Application Kit |
AB |
Address Book |
IB |
Interface Builder |
클래스, 프로토콜, 함수, 상수 및 typedef 구조의 이름을 지정할 때 접두사를 사용하십시오.
메소드의 이름을 지정할 때 Prefix를 사용하지 마십시오.
메소드는 이를 정의하는 클래스가 작성한 네임 스페이스(Private)에 존재합니다.
또한 구조의 필드 이름을 지정할 때 접두사를 사용하지 마십시오
Typographic Conventions
1. 여러 단어로 구성된 이름의 경우 _, - 로 구분하지 마십시오.
2. 메소드 이름의 경우 소문자로 시작하고 포함된 단어의 첫 문자를 대문자로 사용하십시오. 접두사를 사용하지 마십시오
fileExistsAtPath:isDirectory:
이 지침의 예외는 잘 알려진 약어 (예 : TIFFRepresentation (NSImage))로 시작하는 메소드 이름입니다.
3. 함수와 상수의 이름은 관련 클래스와 동일한 접두사를 사용하고 포함된 단어의 첫 글자를 대문자로 사용하십시오.
NSRunAlertPanel
NSCellDisabled
4. 메소드 이름에서 private을 의미하는 접두어로 _ 문자를 사용하지 마십시오.
하지만 인스턴스 변수 이름의 접두어로 밑줄 문자를 사용할 수 있습니다.
Class and Protocol Names
Class
클래스 이름에는 클래스 (또는 클래스의 객체)가 무엇을 나타내는 지 명확하게 나타내는 명사가 포함되어야합니다.
이름에는 적절한 접두사가 있어야 합니다.
NSString, NSDate, NSScanner, NSApplication, UIApplication, NSButton 및 UIButton이 있습니다.
Protocol
프로토콜은 행동을 그룹화하는 방법에 따라 이름을 지정해야 합니다.
대부분의 프로토콜은 특정 클래스와 관련이 없는 관련 방법을 그룹화합니다.
일반적인 규칙은 동명사 ( '... ing') 형식을 사용하는 것입니다
Code | Commentary |
NSLocking |
✅ |
NSLock |
❌나쁨 (class 처럼 보입니다.) (Poor (seems like a name for a class).) |
일부 프로토콜은 여러 개의 별개의 작은 프로토콜을 만드는 대신 관련되지 않은 여러 방법을 그룹화합니다.
이러한 프로토콜은 프로토콜의 주요 표현 인 클래스와 연관되는 경향이 있습니다. 이 경우 규칙은 프로토콜과 클래스 이름을 동일하게 지정하는 것입니다.
Header Files
격리 된 클래스 또는 프로토콜 선언 클래스 또는 프로토콜이 그룹의 일부가 아닌 경우 선언 된 클래스 또는 프로토콜의 이름을 가진 별도의 파일에 선언을 넣으십시오.
Code | Commentary |
NSLocale.h |
NSLocale class 입니다. |
관련 클래스 및 프로토콜 선언 관련 선언 그룹 (클래스, 범주 및 프로토콜)의 경우 기본 클래스, 범주 또는 프로토콜의 이름을 포함하는 파일에 선언을 넣으십시오.
Code | Commentary |
NSString.h |
NSString, NSMutableString class 가 포함되어 있습니다. |
NSLock.h |
NSLocking protoco, NSLock, NSConditionLock, NSRecursiveLock class 가 포함되어 있습니다. |
프레임 워크 헤더 파일 포함 각 프레임 워크에는 프레임 워크의 이름을 딴 헤더 파일이 있어야하며,이 파일에는 프레임 워크의 모든 공용 헤더 파일이 포함됩니다.
Code | Commentary |
Foundation.h |
Foundation.framework. |
다른 프레임 워크의 클래스에 API 추가 한 프레임 워크에서 다른 프레임 워크의 클래스에있는 메소드를 선언하는 경우 원래 클래스의 이름에 '추가'를 추가하십시오. 예를 들어 Application Kit의 NSBundleAdditions.h 헤더 파일이 있습니다.
관련 기능 및 데이터 유형 관련 함수, 상수, 구조 및 기타 데이터 유형 그룹이있는 경우 NSGraphics.h (Application Kit)와 같이 적절하게 명명 된 헤더 파일에 넣습니다.
Naming Methods
General Rules
1. 소문자로 이름을 시작하고 포함 된 단어의 첫 글자를 대문자로 사용하십시오. 접두사를 사용하지 마십시오
두 가지 예외가 있습니다.
TIFF 또는 PDF와 같이 잘 알려진 대문자로 메서드 이름을 시작할 수 있으며 접두사를 사용하여 개인 메서드를 그룹화하고 식별 할 수 있습니다
2. 객체가 취하는 동작을 나타내는 메소드의 경우 동사로 이름을 시작하십시오.
- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem
fun invokeWithTarget(target:)
fun selectTabViewItem(tabViewItem:)
이 보조의 동사는 거의 의미를 추가하지 않으므로 이름의 일부로 'do'또는 'does'를 사용하지 마십시오.
또한 동사 앞에 부사 나 형용사를 사용하지 마십시오
3. 메소드가 수신자의 속성을 리턴하는 경우 속성 뒤에 메소드 이름을 지정하십시오. 하나 이상의 값을 간접적으로 반환하지 않으면 'get'을 사용할 필요가 없습니다.
Code | Commentary |
(NSSize)cellSize |
✅ |
(NSSize)calcCellSize |
❌ |
(NSSize)getCellSize |
❌ |
4. 모든 인수 앞에 키워드를 사용하십시오.
Code | Commentary |
- (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag; |
✅ |
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; |
❌ |
5. Argument을 설명하십시오.
Code | Commentary |
- (id)viewWithTag:(NSInteger)aTag; |
✅ |
- (id)taggedView:(int)aTag; |
❌ |
6. 상속보다 구체적인 방법을 만들 때 기존 함수의 끝에 새 키워드를 추가하십시오.
Code | Commentary |
- (id)initWithFrame:(CGRect)frameRect; |
NSView, UIView. |
- (id)initWithFrame:(NSRect)frameRect mode:(int)aMode cellClass:(Class)factoryId numberOfRows:(int)rowsHigh numberOfColumns:(int)colsWide; |
NSMatrix, a subclass of NSView |
7. 'and'를 사용하여 수신자의 속성 인 키워드를 연결하지 마십시오
Code | Commentary |
- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; |
✅ |
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; |
❌ |
8. 두 가지 별도의 작업을 설명하는 경우“and”를 사용하여 연결하십시오.
Code | Commentary |
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag; |
NSWorkspace |
Accessor Methods
객체의 속성 값을 설정하고 반환하는 메소드입니다. 속성 표현 방법에 따라 특정 권장 양식이 있습니다.
1. 명사로 표시되는 경우 형식은 다음과 같습니다.
- (NSString *)title;
- (void)setTitle:(NSString *)aTitle;
2. 형용사로 표현되면
- (BOOL)isEditable;
- (void)setEditable:(BOOL)flag;
3. 동사로 표현되면
- (BOOL)showsAlpha;
- (void)setShowsAlpha:(BOOL)flag;
동사는 단순 현재 시제에 있어야합니다.
4. 분사를 사용하여 동사를 형용사로 비틀지 마십시오.
Code | Commentary |
- (void)setAcceptsGlyphInfo:(BOOL)flag; |
✅ |
- (BOOL)acceptsGlyphInfo; |
✅ |
- (void)setGlyphInfoAccepted:(BOOL)flag; |
❌ |
- (BOOL)glyphInfoAccepted; | ❌ |
5. 의미를 명확하게하기 위해 모달 동사 (“can”,“should”,“will”등이 앞에 나오는 동사)를 사용할 수 있지만“do”또는“does”는 사용하지 마십시오.
Code | Commentary |
- (void)setCanHide:(BOOL)flag; |
✅ |
- (BOOL)canHide; |
✅ |
- (void)setShouldCloseDocument:(BOOL)flag; |
✅ |
- (BOOL)shouldCloseDocument; | ✅ |
- (void)setDoesAcceptGlyphInfo:(BOOL)flag; | ❌ |
- (BOOL)doesAcceptGlyphInfo; | ❌ |
6. 'get'은 객체와 값을 간접적으로 반환하는 메소드에만 사용하십시오
Code | Commentary |
- (void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase; |
NSBezierPath. |
Delegate Methods
델리게이트 메소드 (또는 델리 게이션 메소드)는 특정 이벤트가 발생할 때 오브젝트가 델리게이트에서 호출하는 메소드입니다
1. 메시지를 보내는 개체의 클래스를 식별하여 이름을 시작하십시오.
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
2. 메소드에 sender 하나의 Argment만 있는 경우가 아니라면 콜론은 클래스 이름 (인수는 위임 오브젝트에 대한 참조 임)에 첨부됩니다.
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
3. 단 하나의 Argment 가 있는 notification 객체는 아래와 같이 표기합니다.
- (void)windowDidChangeScreen:(NSNotification *)notification;
4. 무언가가 발생했거나 일어나고 있음을 대리인에게 알리기 위해 호출 된 메소드에 'did'또는 'will'를 사용하십시오.
- (void)browserDidScroll:(NSBrowser *)sender;
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;
5. 대리인이 다른 개체 대신 무언가를하도록 요청하는 메소드에 대해 'did'또는 'will'을 사용할 수 있지만 'should'가 선호됩니다.
- (BOOL)windowShouldClose:(id)sender;
Collection Methods
객체 컬렉션을 관리하는 객체 (각각 해당 컬렉션의 요소라고 함)의 경우 규칙은 다음과 같은 형식의 메서드를 갖습니다.
- (void)addLayoutManager:(NSLayoutManager *)obj;
- (void)removeLayoutManager:(NSLayoutManager *)obj;
- (NSArray *)layoutManagers;
1. 컬렉션이 정렬되지 않은 경우 NSArray 객체 대신 NSSet 객체를 반환합니다.
2. 컬렉션의 특정 위치에 요소를 삽입해야하는 경우 위의 방법 대신 또는 추가하여 다음과 유사한 방법을 사용하십시오
- (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index;
- (void)removeLayoutManagerAtIndex:(int)index;
3. 삽입 된 객체에 Main 객체에 대한 포인터가 필요한 경우, back pointer를 설정하지만 유지하지 않는 set... 메소드를 사용합니다.
- (void)setTextStorage:(NSTextStorage *)textStorage;
- (NSTextStorage *)textStorage;
NSWindow class 예제
- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
- (void)removeChildWindow:(NSWindow *)childWin;
- (NSArray *)childWindows;
- (NSWindow *)parentWindow;
- (void)setParentWindow:(NSWindow *)window;
Method Arguments
1. 메소드와 마찬가지로 Argemnt는 소문자로 시작하고 연속 단어의 첫 문자는 대문자로 표시됩니다 (예 : removeObject : (id) anObject).
2. 이름에 'pointer', 'ptr'을 사용하지 마십시오.
3. 한 글자와 두 글자로 된 인수를 피하십시오.
4. 몇 글자 만 저장하는 약어는 사용하지 마십시오.
Cocoa 예제
...action:(SEL)aSelector
...alignment:(int)mode
...atIndex:(int)index
...content:(NSRect)aRect
...doubleValue:(double)aDouble
...floatValue:(float)aFloat
...font:(NSFont *)fontObj
...frame:(NSRect)frameRect
...intValue:(int)anInt
...keyEquivalent:(NSString *)charCode
...length:(int)numBytes
...point:(NSPoint)aPoint
...stringValue:(NSString *)aString
...tag:(int)anInt
...target:(id)anObject
...title:(NSString *)aString
Private Methods
대부분의 경우 개인용 메서드 이름은 일반적으로 공용 메서드 이름과 동일한 규칙을 따릅니다.
그러나 일반적인 규칙은 개인용 메서드에 접두사를 지정하여 공용 메서드와 쉽게 구분할 수 있도록 하는 것입니다
1. 밑줄 문자를 개인용 메소드의 접두어로 사용하지 마십시오.
2. 대규모 Cocoa 프레임 워크 클래스 (예 : NSView 또는 UIView)를 서브 클래 싱하고 개인 메소드의 이름이 슈퍼 클래스의 이름과 다른지 확인하려면 개인 메소드에 고유 접두부를 추가 할 수 있습니다.
접두사는 가능한 한 고유해야합니다 (아마도 회사 나 프로젝트 및 'XX_'형식을 기반으로해야합니다).
따라서 프로젝트 이름이 Byte Flogger 인 경우 접두사는 BF_addObject 일 수 있습니다.
그러나 네임 스페이스에서는 접두사를 쓰지 않아도 됩니다.
Naming Functions
싱글톤이거나 분명히 기능적인 서브 시스템 함수에는 다음과 같은 일반적인 명명 규칙이 있습니다.
함수에는 따라야하는 일반적인 명명 규칙이 있습니다.
1. 함수 이름은 메소드 이름과 유사하지만 몇 가지 예외가 있습니다.
- 클래스와 상수에 사용하는 것과 동일한 접두사로 시작합니다.
- 접두사 다음에 나오는 단어의 첫 글자는 대문자입니다.
2. 대부분의 함수 이름은 함수의 효과를 설명하는 동사로 시작합니다.
NSHighlightRect
NSDeallocateObject
속성을 쿼리하는 함수에는 추가 명명 규칙이 있습니다.
1. 함수가 첫 번째 인수의 특성을 리턴하면 동사를 생략하십시오.
unsigned int NSEventMaskFromType(NSEventType type)
float NSHeight(NSRect aRect)
2. 값이 참조로 리턴되면 'Get'을 사용하십시오.
const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsigned int *alignp)
3. 반환 된 값이 Bool인 경우 함수는 변형 된 동사로 시작해야합니다.
BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)
Naming Properties and Data Types
Declared Properties and Instance Variables
1. @property (…) type nounOrVerb;
명사 또는 동사
@property (strong) NSString *title;
@property (assign) BOOL showsAlpha;
2. 선언 된 property의 이름이 형용사로 표현된 경우 property 이름은 'is'접두사를 생략하지만 get 접근 자의 일반적인 이름을 지정합니다
@property (assign, getter=isEditable) BOOL editable;
3. 일반적으로 인스턴스 변수에 직접 액세스하면 안됩니다. 대신 접근자 메소드를 사용해야합니다.
이를 알리기 위해 인스턴스 변수 이름 앞에 밑줄 (_)을 붙입니다.
@implementation MyClass {
BOOL _showsTitle;
}
Constants
Swift 에서는 enum 사용하기 때문에 설명을 생략합니다.
Acceptable Abbreviations and Acronyms
일반적으로 프로그래밍 방식 인터페이스를 디자인 할 때 이름을 줄여서는 안됩니다.
그러나 아래에 나열된 약어는 잘 설정되었거나 과거에 사용되었으므로 계속 사용할 수 있습니다.
Abbreviation | Meaning and comments |
alloc |
Allocate. |
alt |
Alternate. |
app |
Application. For example, NSApp the global application object. However, “application” is spelled out in delegate methods, notifications, and so on. |
calc |
Calculate. |
dealloc |
Deallocate. |
func |
Function. |
horiz |
Horizontal. |
info |
Information. |
init |
Initialize (for methods that initialize new objects). |
int |
Integer (in the context of a C int—for an NSInteger value, use integer). |
max |
Maximum. |
min |
Minimum. |
msg |
|
nib |
Interface Builder archive. |
pboard |
Pasteboard (but only in constants). |
rect |
Rectangle. |
Rep |
Representation (used in class name such as NSBitmapImageRep). |
temp |
Temporary. |
vert |
Vertical. |
참고:
'iOS > Apple Documentation Archive' 카테고리의 다른 글
Framework Programming Guide (0) | 2019.10.01 |
---|---|
Dynamic Library Programming (0) | 2019.09.30 |
Understanding and Analyzing Application Crash Reports (2/2) (0) | 2019.09.23 |
Understanding and Analyzing Application Crash Reports (1/2) (0) | 2019.09.22 |