Objective-C와 Cocoa를 작성할 때 사용하는 베스트 프랙티스는 무엇입니까?
HIG에 대해서는 알고 있습니다만, Objective-C를 쓸 때 어떤 프로그래밍 방법을 사용하고 있는지, 특히 코코아(또는 코코아)를 사용할 때 사용합니다.터치)
표준이 아니라고 생각되는 몇 가지 작업을 시작했습니다.
1) 속성이 등장함에 따라 "프라이빗" 클래스 변수 앞에 "_"를 사용하지 않게 되었습니다.결국 다른 클래스에서 변수에 액세스할 수 있다면 해당 변수에 대한 속성이 있어야 하지 않을까요?코드를 더 못생기게 만드는 접두사 "_"를 항상 싫어했는데, 이제는 생략할 수 있습니다.
2) 프라이빗한 것에 대해서는, 다음과 같이 클래스 확장자의 .m 파일내에 프라이빗한 메서드 정의를 배치하는 것을 선호합니다.
#import "MyClass.h"
@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end
@implementation MyClass
왜 .h파일에 외부인이 신경 쓰지 말아야 할 것들을 어지럽히는 거죠?빈()은 .m 파일의 개인 카테고리에 대해 작동하며 선언된 메서드를 구현하지 않으면 컴파일 경고를 발생시킵니다.
3) dealloc를 .m 파일의 맨 위에 @synthe size 명령어 바로 아래에 배치했습니다.수업 시간에 생각하고 싶은 것 중 가장 중요한 것이 바로 할당 해제 사항이어야 하지 않나요?그것은 특히 아이폰과 같은 환경에서 사실이다.
3.5) Table Cell에서는 모든 요소(셀 자체를 포함)를 불투명하게 하여 성능을 확보한다.즉, 모든 것에 적절한 배경색을 설정하는 것입니다.
3.6) NSURLC Connection을 사용할 때는 원칙적으로 위임 방법을 구현해야 합니다.
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
return nil;
}
대부분의 웹 콜은 매우 특이하며, 특히 웹 서비스 콜의 경우 응답 캐시를 원하는 규칙보다 더 예외적입니다.표시된 메서드를 구현하면 응답 캐시가 비활성화됩니다.
또, Joseph Mattiello(iPhone 메일링 리스트로 수신)의 iPhone 고유의 유용한 힌트도 있습니다.그 밖에도 있습니다만, 이것들은 가장 일반적으로 도움이 된다고 생각합니다(몇 개의 비트가 원문에서 약간 편집되어 응답에 기재되어 있습니다).
4) Core Location 작업 등 필요한 경우에만 2배의 정밀도를 사용하십시오.gcc가 상수를 플로트로 저장하도록 하려면 상수를 'f'로 끝내야 합니다.
float val = someFloat * 2.2f;
이것은 가장 중요한 것입니다.someFloat
스토리지에서 '값'의 정확성을 잃었기 때문에 혼합 모드의 계산은 필요하지 않습니다.iPhone에서는 부동소수점 숫자가 하드웨어에서 지원되지만 단일 정밀도가 아닌 2배 정밀도 산술에 시간이 더 걸릴 수 있습니다.고고: :
구형 전화기에서는 계산은 같은 속도로 동작하지만 레지스터에 2배보다 더 많은 단일 정밀 컴포넌트를 포함할 수 있기 때문에 많은 계산에서 단일 정밀도가 더 빠릅니다.
의 속성을 5) 성성음음음음음음음 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 。nonatomic
그들은atomic
의가 없고 non-atomic으로 더 효율이 향상될 것입니다99%의 사용자는 이 문제에 대해 걱정할 필요가 없으며, 코드를 non-atomic으로 설정하면 훨씬 덜 비대해지고 메모리 효율이 향상됩니다.
세트를 입니다.6) SQLite는 대용량 데이터 세트를 캐시하는 매우 빠른 방법입니다.예를 들어 지도 애플리케이션은 타일을 SQLite 파일에 캐시할 수 있습니다.입출력하다는 많이 쓰지 .BEGIN;
★★★★★★★★★★★★★★★★★」COMMIT;
큰 블록 사이에 있습니다.새로운 송신 마다 리셋 되는 2초의 타이머를 사용하고 있습니다.COMMIT; COMMIT; COMMIT; 인정하다.이것에 의해, 모든 기입이 1 개의 큰 청크로 보내집니다.SQLite는 트랜잭션 데이터를 디스크에 저장하므로 이 시작/종료 래핑을 통해 많은 트랜잭션 파일이 생성되지 않고 모든 트랜잭션을 하나의 파일로 그룹화할 수 있습니다.
「GUI」 「SQL GUI」 「GUI」 「GUI"쿼리가 매우 긴 경우 쿼리를 정적 개체로 저장하고 별도의 스레드에서 SQL을 실행하는 것이 좋습니다.를 변경하는 .@synchronize() {}
록 for. 편리합니다.간단한 문의는 메인 스레드에 남겨두면 편리합니다.
SQLite 최적화에 관한 힌트는 더 많지만, 이 문서의 대부분은 아직 유효하다고 생각됩니다.
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
알 수 없는 문자열을 형식 문자열로 사용하지 않음
메서드 또는 함수가 format string 인수를 사용하는 경우 형식 문자열의 내용을 제어할 수 있는지 확인해야 합니다.
들어 스트링을 때하면 됩니다.NSLog
:
NSString *aString = // get a string from somewhere;
NSLog(aString);
이 문제의 문제는 문자열에 형식 문자열로 해석되는 문자가 포함되어 있을 수 있다는 것입니다.이로 인해 출력 오류, 크래시 및 보안 문제가 발생할 수 있습니다.대신 문자열 변수를 형식 문자열로 대체해야 합니다.
NSLog(@"%@", aString);
다른 환경에서 익숙한 것보다 표준 코코아 명명 및 형식 규칙 및 용어를 사용하십시오.세상에는 많은 코코아 개발자들이 있고, 그들 중 한 명이 당신의 코드로 작업하기 시작할 때, 만약 다른 코코아 코드와 비슷하게 보이고 느껴진다면 훨씬 더 접근하기 쉬울 것이다.
해야 할 일과 하지 말아야 할 일의 예:
- 하지 마세요
id m_something;
오브젝트 인터페이스에서 그것을 멤버 변수 또는 필드라고 부른다; 사용something
★★★★★★★★★★★★★★★★★」_something
인스턴스 변수라고 부릅니다. - getter의 이름을
-getSomething
; 적절한 코코아 이름은 그냥-something
. - 의 을 붙이지
-something:
한다.-setSomething:
- .콜론에는 콜론이 포함되어 있습니다.
-[NSObject performSelector:withObject:]
아니라, 이에요.NSObject::performSelector
. - 언더바(언더스코어)가 아닌 메서드 이름, 파라미터, 변수, 클래스 이름 등에 인터캡(CamelCase)을 사용합니다.
- 클래스 이름은 대문자, 변수 및 메서드 이름으로 시작합니다.
Win16/Win32 스타일의 헝가리 표기법을 사용하지 마십시오.심지어 마이크로소프트도 로의 이동과 함께 그것을 포기했습니다.NET 플랫폼
IBOutlets
지금까지 콘센트의 메모리 관리는 부실했습니다.현재의 베스트 프랙티스는 콘센트를 속성으로 선언하는 것입니다.
@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++ 없음)를 분석할 수 있습니다.설치 및 사용은 간단합니다.
- 이 페이지에서 최신 버전을 다운로드합니다.
- 에서 " " "
cd
프로젝트 디렉토리로 이동합니다. - ★★
scan-build -k -V xcodebuild
.
(특히 디버깅 구성(자세한 내용은 http://clang.llvm.org/StaticAnalysisUsage.html 참조)에서 프로젝트를 분석해야 합니다.단, 그 요점은 대략적으로 다릅니다).
그런 다음 분석기는 컴파일러가 탐지할 수 없는 메모리 관리 및 기타 기본적인 문제를 보여 주는 일련의 웹 페이지를 생성합니다.
이것은 미묘하지만 편리한 것입니다.는 그의 위임자를 리셋합니다.dealloc
.
- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}
이렇게 하면 위임 메서드가 더 이상 전송되지 않습니다. 곧 ★★★dealloc
실수로 더 이상 메시지를 보낼 수 없는 지 확인하고 싶은 에테르 속으로 사라집니다. 오브젝트는 오브젝트( 또는 풀에 의해 될 수 , 라고 말할 이 취소될 공정한 합니다.some Object는 다른 오브젝트(싱글톤 또는 자동 리스 풀 또는 기타 기타)에 의해 유지될 수 있으며, 사용자가 "메시지 전송을 중지합니다!"라고 말할 때까지 해당 오브젝트는 이제 막 할당될 오브젝트를 공정한 게임으로 간주합니다.
이 습관을 들이면 디버깅하기 힘든 많은 이상한 충돌로부터 당신을 구할 수 있습니다.
키 값 관찰 및 NSNotification에도 동일한 원칙이 적용됩니다.
편집:
더욱 방어적인 변화:
self.someObject.delegate = NULL;
다음과 같이 입력합니다.
if (self.someObject.delegate == self)
self.someObject.delegate = NULL;
@paramell
대신:
@interface MyClass (private)
- (void) someMethod
- (void) someOtherMethod
@end
용도:
@interface MyClass ()
- (void) someMethod
- (void) someOtherMethod
@end
Objective-C 2.0의 새로운 기능
클래스 확장은 Apple의 Objective-C 2.0 Reference에 설명되어 있습니다.
"클래스 확장을 사용하면 프라이머리 클래스 @interface 블록 내 이외의 장소에서 클래스에 필요한 추가 API를 선언할 수 있습니다."
즉, 클래스 외에 (개인) 카테고리가 아닌 실제 클래스의 일부입니다.미묘하지만 중요한 차이.
자동 리스를 회피하다
일반적으로 (1)은 라이프 타임을 직접 제어할 수 없기 때문에 자동 리리스된 오브젝트는 비교적 오랫동안 유지되며 애플리케이션의 메모리 용량이 불필요하게 증가할 수 있습니다.데스크톱에서는 이 문제가 거의 발생하지 않을 수 있지만, 제약이 많은 플랫폼에서는 큰 문제가 될 수 있습니다.따라서 모든 플랫폼, 특히 제약이 많은 플랫폼에서는 오브젝트를 자동 리셋하는 메서드를 사용하지 않는 것이 베스트 프랙티스로 간주되며 대신 allocate/init 패턴을 사용하는 것이 좋습니다.
따라서 다음과 같은 것이 아니라
aVariable = [AClass convenienceMethod];
가능한 경우 대신 다음을 사용해야 합니다.
aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];
새로 만든 개체를 반환하는 자신만의 메서드를 작성할 때, 코코아의 명명 규칙을 이용하여 메서드 이름 앞에 "new"를 추가하여 해당 개체를 해제해야 함을 수신자에게 알릴 수 있습니다.
즉, 다음과 같은 것이 아니라
- (MyClass *)convenienceMethod {
MyClass *instance = [[[self alloc] init] autorelease];
// configure instance
return instance;
}
다음과 같이 쓸 수 있습니다.
- (MyClass *)newInstance {
MyClass *instance = [[self alloc] init];
// configure instance
return instance;
}
메서드 이름이 "new"로 시작되므로 API 소비자들은 수신된 개체를 릴리스해야 하는 책임이 있음을 알고 있습니다(예를 들어 NSObjectController의 메서드를 참조하십시오).
(1) 독자적인 로컬 자동 리스 풀을 사용하여 제어할 수 있습니다.자세한 내용은 풀 자동 리스를 참조하십시오.
이들 중 일부는 이미 언급되었지만, 제가 즉석에서 생각할 수 있는 것은 다음과 같습니다.
- KVO 명명 규칙을 따릅니다.지금 KVO를 사용하지 않아도, 제 경험상으로는 앞으로도 도움이 되는 경우가 많습니다.또한 KVO 또는 바인딩을 사용하는 경우에는 정상적으로 동작하고 있음을 알아야 합니다.여기에는 액세스 방법 및 인스턴스 변수뿐만 아니라 대 다의 관계, 검증, 종속 키 자동 알림 등이 포함됩니다.
- 개인 메서드를 범주에 넣습니다.인터페이스뿐만 아니라 구현도 가능합니다.개념적으로 사적인 방법과 사적인 방법 사이에 거리를 두는 것이 좋습니다.나는 모든 것을 내 .m 파일에 포함시킨다.
- 백그라운드 스레드 메서드를 카테고리에 넣습니다.위와 같습니다.본론에 있는 것과 그렇지 않은 것에 대해 생각할 때 명확한 개념적 장벽을 유지하는 것이 좋다는 것을 알게 되었습니다.
- 사용. 보통 내 메서드, 각 하위 클래스의 재정의, 정보 또는 정식 프로토콜에 따라 그룹화합니다.이렇게 하면 내가 찾던 바로 그 곳으로 쉽게 이동할 수 있습니다.같은 토픽에서 유사한 메서드(테이블 뷰의 위임 메서드 등)를 그룹화하여 아무데나 붙이지 마십시오.
- private 메서드와 ivar 앞에 _를 붙입니다.보기에도 좋고, 우연히 소유물을 의미할 때 ivar를 사용할 가능성도 적습니다.
- init & dealloc에서는 뮤테이터 메서드 / 속성을 사용하지 마십시오.나는 그것 때문에 나쁜 일이 일어난 적은 없지만, 당신이 당신의 물건의 상태에 따라 어떤 일을 하는 방법을 바꾸면 나는 이치를 알 수 있다.
- 부동산에 IBOutlets를 넣습니다.사실 이 글을 방금 읽었는데, 지금부터 읽겠습니다.어떤 기억의 이점에도 불구하고 스타일리시하게 (적어도) 더 나은 것 같아요.
- 꼭 필요하지 않은 코드를 작성하지 마십시오.이건 정말 많은 걸 망라하고 있어요. 예를 들어, 아이바를 만들 때
#define
데이터가 필요할 때마다 어레이를 정렬하는 대신 어레이를 캐시할 수 있습니다.이 문제에 대해서는 많은 것을 말할 수 있지만, 중요한 것은, 필요하게 될 때까지 코드를 작성하지 않는 것입니다.그렇지 않으면 프로파일러가 명령합니다.장기적으로는 유지보수가 훨씬 쉬워집니다. - 시작한 일을 끝내라.많은 반제품 버그가 있는 코드가 프로젝트 데드(dead)를 죽이는 가장 빠른 방법입니다.stub 메서드라도 괜찮으시다면 put으로 표시해 주세요.
NSLog( @"stub" )
안에 있거나 어떤 식으로든 상황을 추적하고 싶은 경우.
기입 유닛 테스트코코아에서 다른 틀에서는 더 어려울 수 있는 많은 것들을 테스트할 수 있습니다.예를 들어 UI 코드를 사용하면 일반적으로 연결 상태가 정상인지 확인하고 사용할 때 제대로 작동하는지 신뢰할 수 있습니다.또한 상태를 설정하고 위임 메서드를 쉽게 호출하여 테스트할 수 있습니다.
또한 내부 테스트 작성에 방해가 되는 공개 방법 또는 보호 방법 또는 비공개 방법을 확인할 수 없습니다.
★★★★★★★★★★★★★★★★★★★★★★★★★★.alloc
너release
!
업데이트: ARC를 사용하지 않는 한
Objective-C를 Java/C#/C++/etc인 것처럼 쓰지 마십시오.
자바 EE 웹 어플리케이션 작성에 익숙한 팀이 코코아 데스크톱 어플리케이션을 작성하려고 하는 것을 본 적이 있습니다.마치 자바 EE 웹 애플리케이션인 것처럼.Abstract Foo Factory와 Foo Factory, IFoo와 Foo가 정말 필요한 것은 Foo 클래스와 Fooable 프로토콜뿐이었습니다.
이것을 하지 않는 것은 언어의 차이를 진정으로 이해하는 것입니다.예를 들어 Objective-C 클래스 메서드는 인스턴스 메서드와 동일하게 동적으로 디스패치되며 하위 클래스에서 오버라이드될 수 있으므로 위의 추상 팩토리 및 팩토리 클래스는 필요하지 않습니다.
[ Debugging Magic ]페이지를 북마크 해 주세요.코코아 버그의 근원을 찾으려다 벽에 머리를 부딪힐 때 이곳이 첫 번째 방문지가 되어야 한다.
예를 들어, 나중에 충돌의 원인이 되는 메모리를 처음 할당한 방법을 찾는 방법에 대해 설명합니다(앱 종료 시 등).
내가 뉴비카테고리아홀리즘이라고 부르는 것을 피하도록 노력해라.Objective-C에 처음 온 사람들이 카테고리를 발견하면 그들은 종종 열광하며 존재하는 모든 클래스에 유용한 작은 카테고리를 추가합니다("뭐? 나는 숫자를 로마 숫자로 변환하는 방법을 NSNumber rock on!").
이러지마세요.
당신의 코드는 20여 개의 기초 클래스에 수십 개의 작은 카테고리 메서드를 뿌리면 더 휴대성이 좋고 이해하기 쉬워질 것입니다.
대부분의 경우 일부 코드를 합리화하기 위해 카테고리 메서드가 필요하다고 생각되면 이 메서드를 재사용하지 않습니다.
카테고리 방식(그리고 완전히 미친 DDRIBIN 말고 누가 있을까?)을 네임스페이스에 배치하지 않는 한, Apple, 플러그인, 또는 주소 공간에서 실행되는 다른 어떤 것도 약간 다른 부작용과 함께 같은 이름의 카테고리 방식을 정의할 가능성이 있다.
알겠습니다. 이제 경고를 받았으니 "이 부분 하지 마세요"는 무시하세요.하지만 극도의 자제력을 발휘하라.
세계를 하위 분류하는 것에 저항하라.코코아에서는 다른 프레임워크에서는 하위 분류를 통해 이루어지는 것과 달리 많은 작업이 위임과 기본 실행 시간 사용을 통해 수행됩니다.
들어 에서는 익명 Java 합니다.*Listener
이치노하시는 NETEventArgs
하지 .대신 코코아에서는 둘 다 하지 않습니다.대신 타겟 액션이 사용됩니다.
사용자가 원하는 대로 문자열 정렬
할 때 simple을 .compare:
방법, 예를 들어 지역별 비교 방법, 예를 들어 지역별 비교 방법을 해야 합니다.localizedCompare:
★★★★★★★★★★★★★★★★★」localizedCaseInsensitiveCompare:
.
자세한 내용은 문자열 검색, 비교 및 정렬을 참조하십시오.
선언된 속성
일반적으로 모든 속성에 Objective-C 2.0 선언 속성 기능을 사용해야 합니다.공용이 아닌 경우 클래스 확장에 추가합니다.선언된 속성을 사용하면 메모리 관리 시멘틱스가 즉시 명확해지고 디할로크 메서드를 쉽게 확인할 수 있습니다.속성 선언을 함께 그룹화하면 빠르게 스캔하여 디할로크 메서드의 구현과 비교할 수 있습니다.
속성을 '비원자'로 표시하지 말고 잘 생각해야 합니다.「목표 C 프로그래밍 언어 가이드」에 기재되어 있듯이, 속성은 디폴트로 원자성이며, 상당한 오버헤드가 발생합니다.게다가 단순히 모든 속성을 원자적으로 만든다고 해서 어플리케이션이 스레드 세이프가 되는 것은 아닙니다.또, 물론, 「비원자」를 지정하지 않고, (합성하는 것이 아니라) 독자적인 액세스 메서드를 실장하는 경우는, 그것들을 원자적인 방법으로 실장할 필요가 있는 것에 주의해 주세요.
0의 값을 생각하다
이 질문에서 알 수 있듯이 메시지는nil
목적-C 효 objective objective objective objective-C objective objective objective objective objective objective objective objective만, 코드로 만, 이 기능은, 「」가 , 하기 어려운 .nil
기대하지 않았을 때의 가치입니다.
NSAssert와 친구를 사용합니다.항상 유효한 개체로 0을 사용합니다.특히 Obj-C에서는 메시지를 0으로 보내는 것이 완벽하게 유효합니다.그러나 변수의 상태를 확인하고 싶다면 NSAssert와 NSParameterAssert를 사용하여 문제를 쉽게 추적할 수 있습니다.
간단하지만 자주 잊히는 것.사양에 따라:
일반적으로 같은 실렉터(같은 이름)를 가진 다른 클래스의 메서드도 같은 반환 유형과 인수 유형을 공유해야 합니다.이 제약은 동적 바인딩을 허용하기 위해 컴파일러에 의해 적용됩니다.
이 경우 서로 다른 클래스에 있더라도 동일한 이름 있는 모든 선택기는 동일한 반환/배송 유형을 가진 것으로 간주됩니다.여기 간단한 예가 있습니다.
@interface FooInt:NSObject{}
-(int) print;
@end
@implementation FooInt
-(int) print{
return 5;
}
@end
@interface FooFloat:NSObject{}
-(float) print;
@end
@implementation FooFloat
-(float) print{
return 3.3;
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id f1=[[FooFloat alloc]init];
//prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar
NSLog(@"%f",[f1 print]);
FooFloat* f2=[[FooFloat alloc]init];
//prints 3.3 expectedly as the static type is FooFloat
NSLog(@"%f",[f2 print]);
[f1 release];
[f2 release]
[pool drain];
return 0;
}
Leopard(Mac OS X 10.5) 이상을 사용하는 경우 Instruments 응용 프로그램을 사용하여 메모리 누수를 찾고 추적할 수 있습니다.프로그램을 Xcode로 빌드한 후 [Run]> [ Start with Performance Tool ]> [ Leaks ]를 선택합니다.
앱에 누수가 나타나지 않더라도 물체를 너무 오래 보관하고 있을 수 있습니다.계측기에서 이 작업에 ObjectAlloc 계측기를 사용할 수 있습니다.계측기 문서에서 ObjectAlloc 계측기를 선택하고 View > Detail(보기)을 선택하여 계측기의 세부 정보(아직 표시되지 않은 경우)를 표시합니다(옆에 확인 표시가 있어야 함).ObjectAlloc 세부사항의 "Allocation Life" 아래에서 "Created & Still Living" 옆에 있는 라디오 버튼을 선택해야 합니다.
어플리케이션의 기록을 정지할 때마다 ObjectAlloc 툴을 선택하면 어플리케이션의 각 활성 객체에 대한 참조 수가 [#Net]컬럼에 표시됩니다.자신의 클래스뿐만 아니라 NIB 파일의 최상위 개체 클래스도 확인해야 합니다.예를 들어 화면에 창이 없고 아직 실행 중인 NSWindow에 대한 참조가 표시되는 경우 코드로 릴리스되지 않았을 수 있습니다.
디할로크로 청소합니다.
이것은 잊기 가장 쉬운 것 중 하나입니다. 특히 150mph의 속도로 코딩할 때 그렇습니다.항상, 항상, 어트리뷰트/멤버 변수를 dealloc로 청소해 주세요.
Objc 2 속성을 새로운 도트 표기와 함께 사용하는 것을 좋아하기 때문에 청소가 간단해집니다.대부분의 경우 다음과 같이 단순합니다.
- (void)dealloc
{
self.someAttribute = NULL;
[super dealloc];
}
이렇게 하면 릴리스가 처리되어 속성을 NULL로 설정할 수 있습니다(방어적 프로그래밍을 고려합니다.멤버 변수에 다시 액세스할 때 다른 메서드가 추가될 경우 - 드물지만 발생할 수 있습니다).
10.5에서 GC를 켜면 이 작업은 더 이상 필요하지 않습니다. 그러나 작성한 다른 리소스를 정리해야 할 수도 있습니다. 대신 최종 방법으로 이를 수행할 수 있습니다.
이 모든 코멘트는 훌륭하지만, 얼마 전에 출판된 Google의 Objective-C Style Guide에 대해 언급하지 않은 것이 정말 놀랍습니다.나는 그들이 매우 철저하게 일을 했다고 생각한다.
또한 반관련 토픽(더 많은 답변을 할 수 있는 여지가 있음) :
2년 전에 알았으면 했던 X코드 팁과 속임수는 무엇입니까?
NSWindowController 및 NSViewController는 자신이 관리하는 NIB 파일의 최상위 개체를 릴리스합니다.
NIB 파일을 수동으로 로드하는 경우 NIB의 최상위 개체를 모두 로드한 후 해당 개체를 해제해야 합니다.
초보자용으로는 Xcode의 자동 표시 기능을 사용하는 것이 당연합니다.다른 소스에서 복사/붙여넣기를 하는 경우에도 코드를 붙여넣으면 코드 블록 전체를 선택하고 마우스 오른쪽 버튼을 클릭한 다음 해당 블록 내의 모든 항목을 다시 표시하는 옵션을 선택할 수 있습니다.
Xcode는 실제로 해당 섹션을 해석하고 괄호, 루프 등에 따라 들여씁니다.각 줄마다 스페이스 바나 탭 키를 누르는 것보다 훨씬 효율적입니다.
코코아 프로그래밍에 처음 뛰어들었을 때 이걸 간과했다는 걸 알아요.
NIB 파일에 대한 메모리 관리 책임을 이해하십시오.로드하는 모든 NIB 파일에서 최상위 개체를 해제해야 합니다.이 주제에 대한 Apple의 문서를 읽어 보십시오.
모든 GCC 경고를 켠 다음 Apple 헤더로 인해 정기적으로 발생하는 경고를 해제하여 노이즈를 줄입니다.
또한 Clang 정적 분석을 자주 실행합니다. "Run Static Analyzer" 빌드 설정을 통해 모든 빌드에 대해 이 분석을 활성화할 수 있습니다.
유닛 테스트를 작성하여 각 빌드에서 실행합니다.
변수 및 속성
청결하게 하기/ 구현하기 위해/ 구현하기
헤더에 인스턴스 변수를 포함하지 마십시오.속성으로 클래스 계속에 들어가는 개인 변수.공용 변수는 헤더에서 공용 속성으로 선언됩니다.읽기 전용인 경우 읽기 전용으로 선언하고 클래스 연속에서 읽기 쓰기로 덮어씁니다.기본적으로 변수는 전혀 사용하지 않고 속성만 사용합니다.
2/ 속성에 기본값이 아닌 변수 이름을 지정합니다. 예:
@synthesize property = property_;
이유 1: 속성을 할당할 때 "self"를 잊어버려서 발생하는 오류를 발견하게 됩니다.이유 2: 내 실험 결과, 계측기의 Leak Analyzer가 기본 이름의 누출 속성을 감지하는 데 문제가 있습니다.
3/ 소유물에 직접 보관하거나 해제하지 마십시오(또는 매우 예외적인 경우에만).네 할로우크에서 그냥 0을 할당해라.보유 속성은 보유/해제를 자체적으로 처리하기 위한 것입니다.예를 들어 setter가 옵서버 추가 또는 삭제가 아닌지는 알 수 없습니다.변수는 세터 및 게터 내에서만 직접 사용해야 합니다.
표시
1/ 가능하면 모든 뷰 정의를 xib에 넣습니다(일반적으로 동적 콘텐츠와 레이어 설정은 예외입니다).시간을 절약하고(코드 작성보다 간단하게), 변경도 쉽고, 코드를 깔끔하게 유지합니다.
2/ 뷰 수를 줄여 뷰를 최적화하지 마십시오.서브뷰를 추가하고 싶다고 해서 xib 대신 코드에 UIImageView를 작성하지 마십시오.대신 UIImageView를 배경으로 사용합니다.뷰 프레임워크는 수백 개의 뷰를 문제없이 처리할 수 있습니다.
3/ IBOutlets가 항상 유지(또는 강하게)될 필요는 없습니다.IBOutlet의 대부분은 뷰 계층의 일부이므로 암묵적으로 유지됩니다.
4/ view Did Unload에서 모든 IBOutlets를 해제합니다.
5/ dealloc 메서드에서 viewDidUnload를 호출합니다.암묵적으로 호출되지 않습니다.
기억
1/ 오브젝트를 작성할 때 오브젝트를 자동 리스로 합니다.많은 버그는 릴리스 콜을 하나의 if-else 브랜치로 이동하거나 리턴 스테이트먼트 후에 발생합니다.자동 리스가 아닌 릴리스는 예외적인 상황에서만 사용해야 합니다. 예를 들어 런루프를 기다리는 동안 개체를 너무 일찍 자동 리셋하지 않도록 해야 합니다.
2/ Authomatic Reference Counting(인증 참조 카운트)을 사용하더라도 유지 해제 방식의 구조를 완벽하게 이해해야 합니다.유지 해제를 수동으로 사용하는 것은 ARC보다 복잡하지 않습니다. 두 경우 모두 누출과 유지 사이클에 대해 고려해야 합니다.대규모 프로젝트나 복잡한 객체 계층에서 유지 릴리스를 수동으로 사용하는 것이 좋습니다.
평.
1/ 코드를 자동 인증합니다.모든 변수 이름과 메서드 이름이 해당 작업이 수행되고 있는지 확인합니다.코드가 올바르게 기술되어 있는 경우(많은 연습이 필요), 코드 코멘트는 필요 없습니다(문서 코멘트와는 다릅니다).알고리즘은 복잡할 수 있지만 코드는 항상 단순해야 합니다.
2/ 때로는 코멘트가 필요할 수 있습니다.보통 눈에 띄지 않는 코드 동작 또는 해킹을 기술합니다.코멘트를 쓸 필요가 있다고 생각되는 경우는, 우선 코멘트를 사용하지 않고 간단하게 코드를 고쳐 써 주세요.
들여쓰기
1/ 움푹 패인 부분을 너무 많이 늘리지 마십시오.메서드 코드의 대부분은 메서드레벨로 들여써야 합니다.블록이 중첩되면 가독성이 저하됩니다.내포된 블럭이 세 개인 경우 내부 블럭을 별도의 방법으로 배치해야 합니다.네 개 이상의 중첩된 블록을 사용하지 마십시오.메서드 코드의 대부분이 if 안에 있는 경우는, if 조건을 무효로 합니다.예:
if (self) {
//... long initialization code ...
}
return self;
if (!self) {
return nil;
}
//... long initialization code ...
return self;
C코드, 주로 C구조를 이해한다.
Obj-C는 C 언어를 통한 가벼운 OOP 레이어일 뿐이라는 점에 주의해 주십시오.C의 기본 코드 구조(enum, structure, 배열, 포인터 등)가 어떻게 기능하는지 이해해야 합니다.예:
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20);
다음과 같습니다.
CGRect frame = view.frame;
frame.size.height += 20;
view.frame = frame;
그 밖에도
자체 코딩 표준 문서를 작성하고 자주 업데이트하십시오.당신의 버그로부터 배우도록 노력하세요.버그가 생성된 이유를 이해하고 코딩 표준을 사용하여 버그를 회피합니다.
당사의 코딩 표준은 현재 약 20페이지로 구성되어 있으며, Java 코딩 표준, Google Obj-C/C++ 표준 및 자체 추가가 혼합되어 있습니다.코드를 문서화하고, 표준적인 들여쓰기, 적절한 위치에 공백 및 빈 줄을 사용합니다.
기능성 향상.
Objective-C는 객체 지향 언어이지만, 코코아 프레임워크는 기능적 스타일을 인식하고 있으며, 많은 경우 기능적 스타일을 설계되어 있습니다.
불변성의 분리가 있다.불변 클래스는 프라이머리 오브젝트로, 변경 가능한 오브젝트는 세컨더리로 사용합니다.예를 들어 주로 NSAray를 사용하고 필요한 경우에만 NSMutableArray를 사용하십시오.
순수한 기능이 있습니다.많지는 않지만, 많은 프레임워크 API가 순수한 함수처럼 설계되어 있습니다. 하다, 하다, 하다, 하다 등의 .
CGRectMake()
★★★★★★★★★★★★★★★★★」CGAffineTransformMake()
포인터 폼이 더 효율적입니다.그러나 간접적인 주장과 포인터는 부작용이 없을 수 없다.구조물을 가능한 한 많이 설계합니다.짝수 상태 개체를 구분합니다.-copy
-retain
을른공유 상태는 다른 오브젝트의 값으로의 변환에 사일런트하게 영향을 줄 수 있기 때문입니다.그래서 부작용이 없을 수 없다.외부로부터의따라서 공유 상태를 가능한 한 최소화하는 것도 중요합니다.
하지만 불순한 기능을 사용하는 것도 두려워하지 마세요.
게으른 평가가 있다.「 」와 같은 .
-[UIViewController view]
생성.오브젝트가 생성될 때 뷰가 생성되지 않습니다.가 읽었을 때view
첫 번째 자산입니다.UIImage
실제로 그려질 때까지 로드되지 않습니다.이 설계와 같은 구현이 많이 있습니다.이러한 설계는 자원 관리에 매우 도움이 되지만, 게으른 평가의 개념을 모르면 그 동작을 이해하는 것이 쉽지 않습니다.폐쇄가 있다.가능한 한 C-block을 사용합니다.이것은 당신의 삶을 크게 심플하게 할 것입니다.그러나 사용하기 전에 블록 메모리 관리에 대해 다시 한 번 읽어 보십시오.
GC를 사용하다NSAutorease 풀(NSAutorease 풀) 사용
-autorelease
매뉴얼 사용-retain/-release
명시적 자원 삭제」(: 「메모리 최적화」, 「명시적 자원 삭제」)입니다.
언급URL : https://stackoverflow.com/questions/155964/what-are-best-practices-that-you-use-when-writing-objective-c-and-cocoa
'code' 카테고리의 다른 글
매개 변수가 없는 SQL 주입 방지 (0) | 2023.04.18 |
---|---|
SQL 쿼리를 사용하여 테이블 이름을 변경하려면 어떻게 해야 합니까? (0) | 2023.04.18 |
SQL Server에서 쿼리 시간 초과 강제 적용 (0) | 2023.04.18 |
Bash 스크립트를 종료하기 전에 명령을 실행하는 방법 (0) | 2023.04.13 |
Bash에서 난수를 생성하는 방법은 무엇입니까? (0) | 2023.04.13 |