답변:
내가 생각하기 시작한 몇 가지가 표준이라고 생각하지 않습니다.
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
.무엇을 하든지 Win16 / Win32 스타일 헝가리어 표기법을 사용 하지 마십시오 . 마이크로 소프트조차도 .NET 플랫폼으로 전환하면서 포기했습니다.
역사적으로, 콘센트의 메모리 관리는 열악했습니다. 현재 모범 사례는 콘센트를 속성으로 선언하는 것입니다.
@interface MyClass :NSObject {
NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end
속성을 사용하면 메모리 관리 의미가 명확 해집니다. 또한 인스턴스 변수 합성을 사용하는 경우 일관된 패턴을 제공합니다.
참고 : 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;
Memory Management Programming Guide for Cocoa
: Additional cases of weak references in Cocoa include, but are not restricted to, table data sources, outline view items, notification observers, and miscellaneous targets and delegates. In most cases, the weak-referenced object is aware of the other object’s weak reference to it, as is the case for circular references, and is responsible for notifying the other object when it deallocates.
@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를 선언 할 수 있습니다."
따라서 이들은 실제 수업의 일부이며 수업 외에 (비공개) 카테고리가 아닙니다. 미묘하지만 중요한 차이점.
()
대신에 (Private)
(또는 다른 카테고리 이름) 대신 사용하는 것이 중요한 이점이 있습니다 . 일반인에게만 읽기 전용 인 속성을 읽기 / 쓰기로 다시 선언 할 수 있습니다. :)
일반적으로 (1) 수명을 직접 제어 할 수 없기 때문에 자동 해제 된 객체는 비교적 오랫동안 지속될 수 있으며 응용 프로그램의 메모리 공간을 불필요하게 증가시킬 수 있습니다. 데스크톱에서는 이것이 별다른 영향을 미치지 않지만,보다 제한된 플랫폼에서는 중요한 문제가 될 수 있습니다. 따라서 모든 플랫폼, 특히보다 제한적인 플랫폼에서는 자동 릴리스 된 객체로 이어질 방법을 사용하지 않는 것이 좋습니다. 대신 alloc / init 패턴을 사용하는 것이 좋습니다.
따라서 다음보다는
aVariable = [AClass convenienceMethod];
가능한 경우 대신 다음을 사용해야합니다.
aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];
새로 작성된 객체를 리턴하는 고유 한 메소드를 작성할 때 Cocoa의 이름 지정 규칙 을 사용하여 메소드 이름 앞에 "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의 newObject
메소드 참조 ).
(1) 자체 로컬 자동 릴리스 풀을 사용하여 제어 할 수 있습니다. 이에 대한 자세한 내용은 자동 릴리스 풀을 참조하십시오 .
NSAutoreleasePool
. 그러나 이것이 실제로 문제임을 확인한 후에 만 가능합니다. 조기 최적화 및 그 모든 것
이것들 중 일부는 이미 언급되었지만 다음은 내 머리 꼭대기에서 생각할 수있는 것입니다.
#pragma mark [section]
. 일반적으로 나는 내 자신의 메서드, 각 하위 클래스의 재정의 및 정보 또는 공식 프로토콜별로 그룹화합니다. 이것은 내가 찾고있는 것을 정확하게 건너 뛸 수있게 해줍니다. 같은 주제에서 비슷한 방법 (예 : 테이블 뷰의 대리자 메서드)을 함께 그룹화하지 마십시오.#define
유언장을 할 때 ivar를 만들 거나 데이터가 필요할 때마다 정렬하는 대신 배열을 캐싱하는 것과 같은 많은 것들을 다룹니다 . 내가 이것에 대해 말할 수있는 많은 것이 있지만, 결론은 필요할 때까지 코드를 작성하지 않거나 프로파일 러가 지시합니다. 장기적으로 유지 관리가 훨씬 쉽습니다.NSLog( @"stub" )
안에 넣어서 표시 하거나 물건을 추적하고 싶습니다.Finish what you start
하는 // TODO:
데 사용할 수도 있습니다 .
단위 테스트를 작성하십시오. Cocoa에서는 다른 프레임 워크에서 더 어려울 수 있는 많은 것들을 테스트 할 수 있습니다 . 예를 들어, UI 코드를 사용하면 일반적으로 사물이 연결되어 있는지 확인하고 사용할 때 작동한다는 것을 신뢰할 수 있습니다. 상태를 설정하고 델리게이트 메소드를 쉽게 호출하여 테스트 할 수 있습니다.
또한 내부 테스트를 작성하는 데 방해가되는 공개 vs. 보호 vs. 개인 분석법 가시성이 없습니다.
황금률 : 당신이 alloc
그렇다면 당신 release
!
업데이트 : ARC를 사용하지 않는 한
copy
, mutableCopy
, new
또는 retain
.
Objective-C를 마치 Java / C # / C ++ / etc 인 것처럼 작성하지 마십시오.
한때 Java EE 웹 응용 프로그램을 작성하는 데 사용되는 팀이 Cocoa 데스크탑 응용 프로그램을 작성하는 것을 보았습니다. 마치 Java EE 웹 애플리케이션 인 것처럼. Foo 클래스와 Fooable 프로토콜 만 있으면 필요할 때 AbstractFooFactory와 FooFactory와 IFoo와 Foo가 많이 날았습니다.
이것을하지 않는 것의 일부는 언어의 차이점을 진정으로 이해하는 것입니다. 예를 들어 Objective-C 클래스 메소드는 인스턴스 메소드처럼 동적으로 전달되며 서브 클래스에서 재정의 될 수 있으므로 위의 추상 팩토리 및 팩토리 클래스가 필요하지 않습니다.
내가 지금 Newbiecategoryaholism이라고 부르기로 결정한 것을 피하십시오. Objective-C를 처음 사용하는 사람들은 카테고리를 발견 할 때 종종 존재하는 모든 클래스에 유용한 작은 카테고리를 추가하여 카테고리를 찾는다 ( "무엇입니까? 숫자를 로마 숫자로 변환하여 NSNumber로 변환하는 방법을 추가 할 수 있습니다!" ).
이러지 마
20 가지 기초 클래스 위에 뿌려진 수십 가지의 작은 범주 메소드를 통해 코드를보다 이식 가능하고 이해하기 쉽게 만들 수 있습니다.
대부분의 경우 코드를 간소화하는 데 도움이되는 카테고리 방법이 필요하다고 생각할 때 메소드를 재사용하지 않는 경우가 많습니다.
범주 방법의 이름을 지정하지 않는 한 (그리고 완전히 미친 ddribin 외에 누가 있는가?) Apple이나 플러그인 또는 주소 공간에서 실행되는 다른 항목도 동일한 범주를 정의 할 가능성이 있습니다. 약간 다른 부작용을 가진 같은 이름의 방법 ....
확인. 경고를 받으면 "이 부분을 수행하지 마십시오"를 무시하십시오. 그러나 극단적 인 구속을 행사하십시오.
세계의 서브 클래스 저항. Cocoa에서는 다른 프레임 워크에서 서브 클래 싱을 통해 수행되는 기본 런타임을 위임하고 사용하여 많은 작업을 수행합니다.
예를 들어 Java에서는 익명 인스턴스를 사용합니다. *Listener
서브 클래스 많이 사용하고 .NET에서는 EventArgs
서브 클래스를 많이 사용합니다 . 코코아에서는 타겟 액션이 대신 사용됩니다.
사용자에게 표시 할 문자열을 정렬 할 때는 간단한 compare:
방법을 사용하지 않아야합니다 . 대신 항상 다음과 같은 현지화 된 비교 방법을 사용해야합니다.localizedCompare:
또는localizedCaseInsensitiveCompare:
합니다.
자세한 내용은 문자열 검색, 비교 및 정렬을 참조하십시오 .
일반적으로 모든 특성에 Objective-C 2.0 선언 특성 기능을 사용해야합니다. 공개되지 않은 경우 클래스 확장에 추가하십시오. 선언 된 속성을 사용하면 메모리 관리 시맨틱이 즉시 명확 해지며 할당 해제 방법을보다 쉽게 확인할 수 있습니다. 속성 선언을 함께 그룹화하면 해당 속성을 빠르게 스캔하고 할당 취소 방법의 구현과 비교할 수 있습니다.
속성을 '비 원자'로 표시하지 않기 전에 열심히 생각해야합니다. 으로 언어 가이드 프로그래밍 목적 C 노트, 속성은 기본적으로 원자이며, 발생 상당한 오버 헤드. 또한 모든 속성을 원 자성으로 만들면 응용 프로그램이 스레드로부터 안전하지 않습니다. 물론 '비 원자'를 지정하지 않고 자신의 접근 자 메소드를 구현하지 않고 구현하는 경우 원자 방식으로 구현해야합니다.
NSAssert와 친구를 사용하십시오. 나는 항상 nil을 유효한 객체로 사용합니다 ... 특히 nil로 메시지를 보내는 것은 Obj-C에서 완벽하게 유효합니다. 그러나 변수의 상태를 실제로 확인하려면 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) 이상을 사용하는 경우 계측기 응용 프로그램을 사용하여 메모리 누수를 찾고 추적 할 수 있습니다. Xcode에서 프로그램을 빌드 한 후 실행> 성능 도구로 시작> 누출을 선택하십시오.
앱에 누수가 표시되지 않더라도 물건을 너무 오래 보관할 수 있습니다. 인스트루먼트에서이를 위해 ObjectAlloc 인스트루먼트를 사용할 수 있습니다. 인스트루먼트 문서에서 ObjectAlloc 인스트루먼트를 선택하고보기> 디테일을 선택하여 인스트루먼트의 세부 사항을 표시하십시오 (표시되지 않은 경우) (옆에 확인 표시가 있어야 함). ObjectAlloc 세부 사항의 "할당 수명"아래에서 "생성 및 여전히 생활"옆에있는 단일 선택 단추를 선택하십시오.
이제 응용 프로그램 기록을 중지 할 때마다 ObjectAlloc 도구를 선택하면 "# Net"열에 응용 프로그램의 각 여전히 존재하는 개체에 대한 참조 수가 표시됩니다. 자신의 클래스뿐만 아니라 NIB 파일의 최상위 객체 클래스도 살펴보십시오. 예를 들어, 화면에 창이없고 여전히 살아있는 NSWindow에 대한 참조가 있으면 코드에서 해제하지 않았을 수 있습니다.
dealloc에서 정리하십시오.
이것은 가장 잊어 버리는 것 중 하나입니다-esp. 150mph로 코딩 할 때. 항상, 항상, 할당 해제에서 속성 / 구성원 변수를 정리하십시오.
나는 새로운 점 표기법 과 함께 Objc 2 속성을 사용하고 싶습니다 . 종종 다음과 같이 간단합니다.
- (void)dealloc
{
self.someAttribute = NULL;
[super dealloc];
}
이것은 당신의 릴리스를 돌봐 및 NULL에 대한 속성을 설정합니다 (드물게는하지만 방어 프로그래밍을 고려 - - 경우에 다른 방법을 더 아래의 dealloc에서 다시 멤버 변수를 액세스 할 수있는 일이).
10.5에서 GC를 사용하도록 설정하면 더 이상 필요하지 않지만 생성 한 다른 리소스를 정리해야 할 수도 있습니다. 대신 finalize 메소드에서이를 수행 할 수 있습니다.
이 모든 의견은 훌륭하지만 얼마 전에 출판 된 Google의 Objective-C 스타일 가이드 를 언급 한 사람이 아무도 없습니다 . 나는 그들이 매우 철저한 일을했다고 생각합니다.
또한 반 관련 주제 (응답 공간이 더 필요함) :
초보자가 사용할 수있는 확실한 방법 중 하나는 코드에 Xcode의 자동 들여 쓰기 기능을 사용하는 것입니다. 다른 소스에서 복사 / 붙여 넣기하는 경우에도 코드를 붙여 넣은 후에는 전체 코드 블록을 선택하고 마우스 오른쪽 단추를 클릭 한 다음 해당 블록 내의 모든 항목을 다시 들여 쓰는 옵션을 선택할 수 있습니다.
Xcode는 실제로 해당 섹션을 구문 분석하고 대괄호, 루프 등을 기반으로 들여 쓰기합니다. 각 줄마다 스페이스 바 또는 탭 키를 누르는 것보다 훨씬 효율적입니다.
Cocoa 프로그래밍을 처음 접했을 때 이것을 간과했습니다.
NIB 파일과 관련된 메모리 관리 책임을 이해해야합니다. 로드 한 NIB 파일에서 최상위 레벨 객체를 배포 할 책임이 있습니다. 주제에 관한 Apple의 설명서 를 읽으십시오 .
모든 GCC 경고를 켠 다음, 소음을 줄이기 위해 Apple 헤더에서 정기적으로 발생하는 경고를 끄십시오.
또한 Clang 정적 분석을 자주 실행하십시오. "Run Static Analyzer"빌드 설정을 통해 모든 빌드에 대해 활성화 할 수 있습니다.
단위 테스트를 작성하고 각 빌드마다 실행하십시오.
변수와 속성
1 / 헤더를 깨끗하게 유지하고 구현 숨기기 헤더에
인스턴스 변수를 포함시키지 마십시오. 개인 변수는 클래스 연속에 속성으로 사용됩니다. 공용 변수는 헤더에서 공용 속성으로 선언합니다. 읽기 전용이어야하는 경우 읽기 전용으로 선언하고 클래스 연속에서 읽기 쓰기로 덮어 씁니다. 기본적으로 변수를 전혀 사용하지 않고 속성 만 사용합니다.
2 / 속성에 기본이 아닌 변수 이름을 지정하십시오 (예 :
@synthesize property = property_;
이유 1 : "자기"를 잊어 버린 오류를 발견하게됩니다. 속성을 할당 할 때 이유 2 : 내 실험에서 계측기의 누출 분석기에 기본 이름으로 누수 속성을 감지하는 데 문제가 있습니다.
3 / 재산에서 직접 유지 또는 방출을 사용하지 마십시오 (또는 예외적 인 상황에서만). 당신의 dealloc에서 그들에게 nil을 할당하십시오. 유지 속성은 자체적으로 유지 / 해제를 처리하기위한 것입니다. 세터가 관찰자를 추가 또는 제거하지 않는지 여부는 알 수 없습니다. 변수는 setter 및 getter 내에서만 직접 사용해야합니다.
견해
1 / 가능하면 모든 뷰 정의를 xib에 넣으십시오 (일반적으로 동적 컨텐츠 및 레이어 설정은 예외). 시간을 절약하고 (코드를 작성하는 것보다 쉽습니다) 변경하기 쉽고 코드를 깨끗하게 유지합니다.
2 / 뷰 수를 줄여 뷰를 최적화하지 마십시오. 하위 뷰를 추가하기 위해 xib 대신 UIImageView를 코드에 작성하지 마십시오. 대신 UIImageView를 배경으로 사용하십시오. 뷰 프레임 워크는 문제없이 수백 개의 뷰를 처리 할 수 있습니다.
3 / IBOutlet을 항상 유지할 필요는 없습니다. 대부분의 IBOutlet은 뷰 계층의 일부이므로 암시 적으로 유지됩니다.
4 / viewDidUnload에서 모든 IBOutlet을 해제하십시오.
5 / dealloc 메소드에서 viewDidUnload를 호출하십시오. 암시 적으로 호출되지는 않습니다.
기억
1 / Autorelease 객체를 만들 때. 릴리스 호출을 하나의 if-else 브랜치 또는 return 문 다음으로 이동하면 많은 버그가 발생합니다. 자동 릴리스 대신 릴리스는 예외적 인 상황에서만 사용해야합니다. 예를 들어 런 루프를 기다리는 동안 개체를 너무 빨리 자동 릴리스하지 않으려는 경우.
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의 기본 코드 구조 (열거, 구조체, 배열, 포인터 등)가 어떻게 작동하는지 이해해야합니다. 예:
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는 객체 지향 언어이지만 Cocoa 프레임 워크는 기능적 스타일을 인식하며 많은 경우 기능적 스타일로 설계되었습니다.
가변성의 분리가 있습니다. 불변 클래스를 기본으로 사용하고 가변 객체를 보조로 사용하십시오 . 예를 들어 NSArray를 주로 사용하고 필요할 때만 NSMutableArray를 사용하십시오.
순수한 기능이 있습니다. 그리 많지 않은 많은 API를 구입하면 순수한 기능처럼 설계됩니다. CGRectMake()
또는 과 같은 기능을 살펴보십시오 CGAffineTransformMake()
. 분명히 포인터 형식이 더 효율적으로 보입니다. 그러나 포인터를 사용한 간접적 인 주장은 부작용이 없습니다. 가능한 한 순수하게 구조를 설계하십시오. 짝수 상태 객체를 분리하십시오. 다른 객체에 값을 전달할 때 -copy
대신 사용하십시오 -retain
. 공유 상태는 다른 객체의 가치에 대한 돌연변이에 자동으로 영향을 줄 수 있기 때문입니다. 따라서 부작용이 없어야합니다. object에서 external의 값이 있으면 복사하십시오. 따라서 가능한 한 공유 상태를 설계하는 것도 중요합니다.
그러나 불순한 기능을 사용하는 것을 두려워하지 마십시오.
게으른 평가가 있습니다. -[UIViewController view]
재산 과 같은 것을보십시오 . 객체가 생성 될 때 뷰가 생성되지 않습니다. 발신자 view
가 처음 속성을 읽을 때 생성됩니다 . UIImage
실제로 그려 질 때까지로드되지 않습니다. 이 디자인과 같은 많은 구현이 있습니다. 이러한 종류의 디자인은 리소스 관리에 매우 도움이되지만 지연 평가의 개념을 모르면 해당 동작을 이해하기가 쉽지 않습니다.
폐쇄가 있습니다. C 블록을 가능한 많이 사용하십시오. 이것은 당신의 인생을 크게 단순화시킬 것입니다. 그러나 사용하기 전에 블록 메모리 관리에 대해 한 번 더 읽으십시오.
반자동 GC가 있습니다. NSAutoreleasePool. -autorelease
기본을 사용하십시오 . -retain/-release
필요할 때 수동 보조를 사용하십시오 . (예 : 메모리 최적화, 명시 적 리소스 삭제)
autorelease
일반적으로 메모리를 더 오래 보유 할 것이며, 수동 retain/release
은이 경우 메모리 소비를 줄일 수 있다고 동의합니다 . 그러나 특별한 경우 최적화에 대한 지침이어야합니다 (항상 기분이 좋습니다!) . 조기 최적화를 연습 으로 일반화하는 이유는 아닙니다 . 사실, 당신의 제안은 저와 반대가 아닙니다. 나는 그것을 정말로 필요한 경우로 언급했다 :)