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 ++ 없음)를 놀랍게도 분석 할 수 있습니다. 설치하고 사용하는 것은 간단합니다.
(추가 제약 사항 등이 있습니다. 특히 “디버그”구성에서 프로젝트를 분석해야 합니다. 자세한 내용 은 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를 선언 할 수 있습니다.”
따라서 이들은 실제 수업의 일부이며 수업 외에 (비공개) 카테고리가 아닙니다. 미묘하지만 중요한 차이점.