[iphone] Objective-C 및 Cocoa를 작성할 때 사용하는 모범 사례는 무엇입니까? [닫은]

HIG (아주 편리합니다!) 에 대해 알고 있지만 Objective-C를 작성할 때, 특히 Cocoa (또는 CocoaTouch)를 사용할 때 어떤 프로그래밍 방식을 사용합니까?



답변

내가 생각하기 시작한 몇 가지가 표준이라고 생각하지 않습니다.

1) 속성의 출현으로 더 이상 “_”를 사용하여 “비공개”클래스 변수를 접두사로 사용하지 않습니다. 결국 다른 클래스에서 변수에 액세스 할 수 있다면 속성이 없어야합니까? 나는 코드를 더 못 생기게 만들기 위해 항상 “_”접두어를 싫어했고 이제는 생략 할 수있다.

2) 개인적인 것들에 관해서는, 개인 메소드 정의를 .m 파일 내에 클래스 확장으로 배치하는 것을 선호합니다.

#import "MyClass.h"

@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end

@implementation MyClass

외부인이 신경 써서는 안되는 것들로 .h 파일을 어지럽히는 이유는 무엇입니까? empty ()는 .m 파일의 개인 범주에 대해 작동하며 선언 된 메소드를 구현하지 않으면 컴파일 경고를 발행합니다.

3) dealloc을 @synthesize 지시문 바로 아래의 .m 파일 상단에 두었습니다. 당신이 다루고있는 것이 당신이 수업에서 생각하고 싶은 것들 목록의 최상위에 있지 않아야합니까? iPhone과 같은 환경에서 특히 그렇습니다.

3.5) 표 셀에서 성능을 위해 모든 요소 (셀 자체 포함)를 불투명하게 만듭니다. 그것은 모든 것에 적절한 배경색을 설정하는 것을 의미합니다.

3.6) NSURLConnection을 사용할 때 델리게이트 메소드를 구현하는 것이 좋습니다.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
      return nil;
}

대부분의 웹 호출은 매우 독특하며 특히 웹 서비스 호출의 경우 응답을 캐시하려는 규칙보다 예외입니다. 표시된대로 방법을 구현하면 응답 캐싱이 비활성화됩니다.

Joseph Mattiello (iPhone 메일 링리스트에서 수신)의 유용한 iPhone 관련 팁도 있습니다. 더 많은 것이 있지만 이것들은 내가 생각한 가장 일반적으로 유용했습니다 (응답에 제공된 세부 사항을 포함하기 위해 원본에서 약간의 비트가 약간 편집되었습니다).

4) CoreLocation으로 작업 할 때와 같이 필요한 경우에만 배정 밀도를 사용하십시오. gcc가 부동 소수점으로 저장하도록 상수를 ‘f’로 끝내십시오.

float val = someFloat * 2.2f;

이것은 someFloat실제로 두 배가 될 때 가장 중요 합니다. 저장소에서 ‘val’의 정밀도를 잃기 때문에 혼합 모드 수학이 필요하지 않습니다. 부동 소수점 숫자는 iPhone의 하드웨어에서 지원되지만 단 정밀도와는 달리 배정 밀도 산술을 수행하는 데 여전히 더 많은 시간이 걸릴 수 있습니다. 참고 문헌 :

구형 전화에서는 계산 속도가 동일하지만 두 배보다 레지스터에 더 많은 단 정밀도 구성 요소를 가질 수 있으므로 많은 계산에서 단 정밀도가 더 빨라집니다.

5) 속성을로 설정하십시오 nonatomic. 그것들은 atomic기본적으로 있으며 합성시 멀티 스레딩 문제를 방지하기 위해 세마포어 코드가 생성됩니다. 99 %의 사람들은 아마도 이것에 대해 걱정할 필요가 없으며 비 원자로 설정하면 코드가 훨씬 덜 부풀어지고 메모리 효율적입니다.

6) SQLite는 대용량 데이터 세트를 캐시하는 매우 빠르고 빠른 방법입니다. 예를 들어지도 응용 프로그램은 타일을 SQLite 파일로 캐시 할 수 있습니다. 가장 비싼 부분은 디스크 I / O입니다. 큰 블록 을 보내 BEGIN;거나 COMMIT;큰 블록 사이 에 많은 작은 쓰기를 피하십시오 . 예를 들어 새로운 제출마다 재설정되는 2 초 타이머를 사용합니다. 만료되면 COMMIT를 보냅니다. 모든 쓰기가 하나의 큰 덩어리로 진행됩니다. SQLite는 트랜잭션 데이터를 디스크에 저장하고이 시작 / 종료 래핑을 수행하면 많은 트랜잭션 파일을 만들지 않고 모든 트랜잭션을 하나의 파일로 그룹화 할 수 있습니다.

또한 SQL이 기본 스레드에 있으면 GUI가 차단됩니다. 쿼리가 매우 긴 경우 쿼리를 정적 개체로 저장하고 별도의 스레드에서 SQL을 실행하는 것이 좋습니다. 쿼리 문자열에 대한 데이터베이스를 @synchronize() {}블록 단위로 수정하는 모든 항목을 래핑하십시오 . 짧은 쿼리의 경우 주 스레드에 물건을두면 더 편리합니다.

더 많은 SQLite 최적화 팁이 여기 있지만, 문서가 구식으로 보이지만 많은 점이 여전히 아마도 좋습니다.

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html


답변

알 수없는 문자열을 형식 문자열로 사용하지 마십시오

메서드 나 함수가 형식 문자열 인수를 사용할 때는 형식 문자열의 내용을 제어 할 수 있어야합니다.

예를 들어, 문자열을 로깅 할 때 문자열 변수를 유일한 인수로 NSLog다음 과 같이 전달하려고합니다 .

    NSString *aString = // get a string from somewhere;
    NSLog(aString);

이에 대한 문제점은 문자열에 형식 문자열로 해석되는 문자가 포함될 수 있다는 것입니다. 이로 인해 잘못된 출력, 충돌 및 보안 문제가 발생할 수 있습니다. 대신 문자열 변수를 형식 문자열로 대체해야합니다.

    NSLog(@"%@", aString);


답변

다른 환경에서 익숙하지 않은 표준 Cocoa 이름 지정 및 형식 지정 규칙과 용어를 사용하십시오. 많은 Cocoa 개발자 가 있으며 다른 개발자가 코드 작업을 시작할 때 다른 Cocoa 코드와 비슷하게 보이고 느껴지면 훨씬 더 접근하기 쉽습니다.

해야 할 것과하지 말아야 할 것의 예 :

  • id m_something;객체의 인터페이스에서 선언하지 말고 그것을 멤버 변수 또는 필드 라고 부릅니다 . something또는 _something이름을 사용 하여 인스턴스 변수 라고합니다 .
  • 게터의 이름을 지정하지 마십시오 -getSomething. 적절한 코코아 이름은 -something입니다.
  • 세터의 이름을 지정하지 마십시오 -something:. 그것은해야한다-setSomething:
  • 메소드 이름은 인수와 함께 배치되며 콜론을 포함합니다. 그건 -[NSObject performSelector:withObject:]아니고 NSObject::performSelector.
  • 밑줄 (밑줄) 대신 메소드 이름, 매개 변수, 변수, 클래스 이름 등에 인터 캡 (CamelCase)을 사용하십시오.
  • 클래스 이름은 대문자, 변수 및 메소드 이름으로 소문자로 시작합니다.

무엇을 하든지 Win16 / Win32 스타일 헝가리어 표기법을 사용 하지 마십시오 . 마이크로 소프트조차도 .NET 플랫폼으로 전환하면서 포기했습니다.


답변

IB 아울렛

역사적으로, 콘센트의 메모리 관리는 열악했습니다. 현재 모범 사례는 콘센트를 속성으로 선언하는 것입니다.

@interface MyClass :NSObject {
    NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end

속성을 사용하면 메모리 관리 의미가 명확 해집니다. 또한 인스턴스 변수 합성을 사용하는 경우 일관된 패턴을 제공합니다.


답변

LLVM / Clang 정적 분석기 사용

참고 : Xcode 4에서는 이제 IDE에 내장되어 있습니다.

Clang Static Analyzer 를 사용하여 Mac OS X 10.5에서 C 및 Objective-C 코드 (아직 C ++ 없음)를 놀랍게도 분석 할 수 있습니다. 설치하고 사용하는 것은 간단합니다.

  1. 이 페이지 에서 최신 버전을 다운로드 하십시오 .
  2. 명령 행에서 cd프로젝트 디렉토리로.
  3. 실행합니다 scan-build -k -V xcodebuild.

(추가 제약 사항 등이 있습니다. 특히 “디버그”구성에서 프로젝트를 분석해야 합니다. 자세한 내용 은 http://clang.llvm.org/StaticAnalysisUsage.html 을 참조하십시오 . 그것은 무엇으로 귀결됩니다.)

그런 다음 분석기는 메모리 관리 및 컴파일러가 감지 할 수없는 기타 기본 문제를 보여주는 일련의 웹 페이지를 생성합니다.


답변

이것은 미묘하지만 편리한 것입니다. 다른 객체의 대리자로 자신을 전달하는 경우 먼저 해당 객체의 대리자를 재설정하십시오 dealloc.

- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}

이렇게하면 더 이상 대리자 메서드가 전송되지 않습니다. 당신에 대해이야으로 dealloc에테르로 사라 당신은 확실히 아무 실수로 당신에게 더 이상 메시지를 보낼 수 없음을 만들고 싶어. self.someObject는 다른 객체 (단일 또는 오토 릴리즈 풀 등)에 보관 될 수 있으며 “메시지를 보내지 마십시오!”라고 말할 때까지는 단지 해제 할 대상이라고 생각합니다. 공정한 게임입니다.

이 습관에 들어가면 디버그하기 힘든 이상한 충돌을 피할 수 있습니다.

동일한 보안 주체가 키 값 관찰 및 NSNotifications에도 적용됩니다.

편집하다:

훨씬 더 방어적인 변화 :

self.someObject.delegate = NULL;

으로:

if (self.someObject.delegate == self)
    self.someObject.delegate = NULL;


답변

@kendell

대신에:

@interface MyClass (private)
- (void) someMethod
- (void) someOtherMethod
@end

사용하다:

@interface MyClass ()
- (void) someMethod
- (void) someOtherMethod
@end

Objective-C 2.0의 새로운 기능.

클래스 확장은 Apple의 Objective-C 2.0 참조에 설명되어 있습니다.

“클래스 확장을 사용하면 기본 클래스 @interface 블록 이외의 위치에 클래스에 대한 추가 필수 API를 선언 할 수 있습니다.”

따라서 이들은 실제 수업의 일부이며 수업 외에 (비공개) 카테고리가 아닙니다. 미묘하지만 중요한 차이점.