Objective-C 로 프로 그래 밍(3)

5566 단어 Objective-C
이번 의 내용 은 주로 클래스 의 확장 이다.OC 에서 정 의 된 클래스 에 대해 우 리 는 그것 을 확장 할 수 있다.확장 방안 은 두 가지 가 있 는데 하 나 는 유형 을 통 해 확장 하 는 것 이 고 다른 하 나 는 확장 을 통 해 확장 하 는 것 이다.
먼저 기 존 클래스 를 확장 하 는 의 미 를 말씀 드 리 겠 습 니 다.어떤 때 는 우리 가 하나의 클래스 를 설계 할 때 일부 기능 이 있 을 수 있 고 유 니 버 설 성 을 갖 추 지 못 할 수도 있 습 니 다.이런 기능 들 은 사용 하 는 환경 에 따라 변화 가 생 길 수 있 습 니 다.이 럴 때 우 리 는 확장 방식 을 통 해 서로 다른 환경 에서 서로 다른 방법 으로 문 제 를 해결 할 수 있 습 니 다.그 다음으로 코코아 프레임 워 크 의 유형 에 대해 우 리 는 특정한 기능 이 필요 하지만 없 을 때 우 리 는 스스로 추가 할 수 있다.
클래스 확장 에 대한 첫 번 째 방법 은 클래스 를 직접 사용 하여 확장 하 는 것 이다.클래스 를 사용 하여 확장 할 때 우 리 는 해당 하 는 클래스 에 방법 을 추가 하 는 것 이다.그것 의 문법 은 다음 과 같다.
@interface ClassName (CategoryName)

@end

분 류 를 사용 할 때 우리 가 소스 코드 를 가지 고 있 는 지 여 부 는 중요 하지 않 습 니 다.이 클래스 가 현재 프로젝트 에 존재 하 는 지 확인 하면 됩 니 다.물론 이것 은 주로 코아 프레임 워 크 의 클래스 에 대한 것 입 니 다.만약 에 우리 가 분 류 를 사용 하여 하나의 유형 에 방법 을 추가 하면 이런 유형의 모든 인 스 턴 스 는 이런 방법 을 가지 게 될 것 입 니 다.하위 클래스 라 도 이런 방법 을 계승 할 것 입 니 다.유일한 제한 은 분 류 를 효력 을 발생 시 키 려 면 사용 하 는 파일 에 해당 하 는 헤더 파일 을 도입 해 야 합 니 다.그렇지 않 으 면 우리 가 사용 하 는 것 은 원래 의 클래스 입 니 다.일반적으로 카 테 고리 파일 은 헤더 파일 과 구현 파일 을 작성 합 니 다.이름 만 약간 다 릅 니 다.보통 ClassName+CategoryName 형식 입 니 다.사용 할 때 이 헤더 파일 만 도입 하면 됩 니 다.
실제 유형 은 원래 의 유형 을 확대 하 는 것 을 제외 하고 우리 가 디자인 할 때의 사고 로 도 사용 할 수 있다.이것 은 우리 가 하나의 실현 을 분리 할 수 있다 는 것 을 의미한다.그러면 디자인 류 를 디자인 할 때 비교적 복잡 한 방법 을 고려 하거나 특정한 방법 을 추출 한 다음 에 하나의 유형 으로 따로 설정 하여 처리 하면 이런 구조 와 기능 이 더욱 뚜렷 해진 다.
그러나 분 류 를 사용 할 때 몇 가지 주의해 야 할 것 이 있 습 니 다.먼저 속성의 문제 입 니 다.문법 적 으로 우 리 는 분류 에서 하나의 속성 을 설명 하 는 것 은 문제 가 없 지만 컴 파일 러 는 우리 에 게 해당 하 는 인 스 턴 스 변수 와 방문 방법 을 생 성하 지 않 기 때문에 대체적으로 아무런 역할 을 하지 않 습 니 다.저 는 개인 적 으로 컴 파일 러 에서 도 컴 파일 할 때 경 고 를 해 야 한다 고 생각 합 니 다.유형 에서 하나의 속성 을 밝 히 면 가장 직접적인 문 제 는 바로 이름 을 바 꾸 는 것 입 니 다.특히 코코아 라 이브 러 리 의 유형 에 있어 서 이름 을 바 꾸 면 많은 문제 가 해결 되 지 않 고 직접 사용 하지 않 는 것 이 좋 은 조치 입 니 다.라 이브 러 리 의 유형 에 있어 서작업 할 인 스 턴 스 변 수 는 이미 정의 되 었 습 니 다.또 하나의 중요 한 문 제 는 바로 유형의 이름 을 바 꾸 는 문제 입 니 다.코코아 라 이브 러 리 에 이미 적 힌 클래스 이기 때문에 사실은 유형의 형식 을 사용 하여 일부 조작 을 분류 하기 때문에 쓸 때 이름 을 바 꿀 수 있 습 니 다.그리고 코코아 라 이브 러 리 가 업 데 이 트 된 후에 자신 이 쓴 충돌 이 없 는 유형 도 업데이트 에 따라 충돌 할 수 있 습 니 다.따라서 분류 이름 을 붙 일 때 도 주의해 야 한다.공식 문서 가 우리 에 게 준 해결 방안 은 세 개의 대문자 로 맨 앞 에 놓 는 동시에 유형 중의 방법 명 에 도 이름 이 바 뀔 수 있다 는 것 이다.방법 명 에 대해 서도 세 개의 자 모 를 사용 하지만 소문 자 형식 이 고 밑줄 과 실제 방법 명 으로 구분 하 는 것 이다.구체 적 인 상황 은 다음 과 같다.
@interface NSSortDescriptor (XYZAdditions)

+ (id)xyz_sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending;

@end

이렇게 하 는 장점 중 하 나 는 이름 을 바 꾸 는 것 을 방지 하 는 것 이다.또한 방법 명 에 대해 컴 파일 단계 에서 호출 방법 을 확인 할 수 있다.(방법의 이름 바 꾸 기 는 컴 파일 할 때의 경고 가 나타 나 지 않 지만,호출 할 때 어떤 방법 을 호출 할 지 확인 할 수 없습니다)
위 에서 말 한 것 은 유형 을 통 해 한 가지 유형 을 확대 하 는 것 이다.그러나 이런 방식 의 한계점 도 매우 뚜렷 하 다.우 리 는 자신 이 설정 한 유형 에 대해 확장 을 하고 방법 만 확대 할 수 있 으 며 많은 위험 도 있다.애플 은 실제로 우리 에 게 또 다른 확장 방식 을 제공 했다.그것 은 바로 클래스 를 바탕 으로 확장 하 는 것 이다.이런 방법 은 반드시 소스 코드 를 가 져 야 한다 고 요구한다.실제로 이런 방식 은 우리 가 자주 접 할 것 이다.
확장 은 쓰기 에서 볼 때 유형 과 차이 가 많 지 않 지만 원본 코드 를 가 져 야 하고 컴 파일 할 때 효력 이 발생 하 며 원본 코드 에 대응 하 는 클래스 로 컴 파일 해 야 합 니 다.이것 이 바로 원본 코드 가 있어 야 사용 할 수 있 는 이유 입 니 다.그래서 Cocoa 의 클래스 에 대해 서 는 사용 할 수 없습니다.이 방식 의 쓰 기 는 다음 과 같다.
@interface ClassName ()

@end

맞 아,이 건 카 테 고리 와 똑 같 아 보 여.카 테 고리 이름 이 없 을 뿐 이 야.그러나 이 역할 은 분류 와 다 릅 니 다.특히 속성 추가 와 인 스 턴 스 변 수 를 지원 합 니 다.이렇게 확장 에서 속성 을 설명 하면:
@interface XYZPerson ()
@property NSObject *extraProperty;
@end;

컴 파일 러 는 인 스 턴 스 변 수 를 생 성 합 니 다extraProperty 및 setter/getter,그리고 이 내용 들 은 원본 클래스 로 컴 파일 됩 니 다.심지어 확장 과정 에서 하나의 방법 을 설명 한다 면 이러한 실현 에서 도 반드시 이 방법 을 실현 해 야 한다.
클래스 의 확장 방법,속성 은 기본적으로 원래 클래스 에서 직접 설명 하 는 것 과 별 차이 가 없 는 이상,왜 우 리 는 이러한 확장 이 필요 합 니까?우 리 는 모두 알 고 있 습 니 다.이러한 성명 은 외부 구성원 들 에 게 일련의 인 터 페 이 스 를 제공 하 는 것 입 니 다.다시 말 하면 이런 인 터 페 이 스 는 공유 인터페이스 입 니 다.사실 다른 언어 에서 OC 로 넘 어 온 사람 에 게 가장 큰 의문 은 원래 의 방문 권한 은?예전 에는 Public 와 private 가 있 었 는데 OC 에 서 는 하필 없 었 다 는 것 이다.실제로 이것 은 OC 자체 의 사고방식 과 관련 이 있다.처음에 정 의 된 인 터 페 이 스 는 바로 우리 의 공공 인터페이스 이다.외 부 는 마음대로 방문 할 수 있 지만 우리 가 확장 을 통 해 방법 이나 속성 을 정의 하면 이것 이 바로 우리 가 정의 한 개인 구성원 이다.외 부 는 직접 방문 할 수 없다.그러면 OC 는 간접 적 으로 방문 권한 의 제 어 를 실현 할 수 있다.또한 OC 에 비교적 독특한 것 이 있 습 니 다.그것 은 바로 읽 을 수 있 고 쓸 수 있 으 며 읽 을 수 있 습 니 다.이것 은 어느 정도 에 코드 를 쓰 는 번 거 로 움 을 증가 시 켰 습 니 다.만약 에 하나의 속성 이 외부 변수 가 그 값 만 얻 고 수정 할 수 없 기 를 원한 다 면 저 는 readonly 라 고 성명 한 다음 에 이러한 여러 방법 에서 인 스 턴 스 변 수 를 통 해 방문 해 야 합 니 다.그러나 이 는 하필 이면 OC 가 추천 한 init 방법 에서 만 직접 방문 하 는 것 과 어 긋 난다.이 럴 때 클래스 확장 을 통 해 이 문 제 를 해결 할 수 있 습 니 다.예 를 들 어 클래스 중간 에 저 는 속성 을 readonly 로 설정 한 다음 에 확장 에서 readwrite 로 설정 하면 외부 에 있 을 때 getter 방법 만 제공 하고 내부 에 있 을 때 setter 방법 을 사용 할 수 있 습 니 다.(물론 readwrite 는 기본 이 므 로 다시 설명 하면 됩 니 다)
특히 컴 파일 러 에 있어 서 이렇게 많은 것 을 개의 치 않 습 니 다.당신 의 속성 이 readwrite 가 존재 한다 면 setter 와 getter 를 동시에 생 성 할 것 입 니 다.그래서 실제 실행 하 는 과정 에서 당신 의 코드 에는 setter 가 존재 합 니 다.다만 readonly 속성 에 대한 접근 은 컴 파일 러 를 컴 파일 단계 에서 통과 하지 못 하 게 할 것 입 니 다.그러나...저 희 는 사실 performSelector 방법 도 있 습 니 다.setter 를 직접 호출 할 수 있 기 때문에 이러한 계승 과 디자인 을 고려 할 때 이 점 을 잘 고려 해 야 합 니 다.계승 시스템 에서 setter 에 대한 호출 은 최종 적 으로 원 하 는 방법 이 아 닐 수 있 습 니 다.
사실은 확 장 된 문법 을 보 았 을 때 당신 은 이미 알 아 차 렸 을 것 입 니 다.실제로 많은 소스 코드 에서 이렇게 사용 되 었 습 니 다.바로 클래스 의 실현 파일 위 에 하나의 확장 을 썼 습 니 다.처음에 공 부 를 시 작 했 을 때 이런 코드 를 보면 의 심 스 러 울 수 있 지만 지금 은 이 코드 들 을 모두 가 이해 할 수 있 을 것 입 니 다.
또 유형 이 든 확장 이 든 유형 을 확장 하 는 가장 좋 은 수단 은 아니다.OC 는 표면적 인 대상 을 대상 으로 하 는 언어 이기 때문에 우 리 는 대상 이라는 개념 을 고려 해 야 한다.코드 의 중용 성 을 어떻게 향상 시 키 는 지 고려 해 야 하기 때문에 일정한 상황 에서 우 리 는 유형 을 확대 할 필요 가 없고 서브 클래스 를 직접 정의 하 는 것 이 오히려 더 좋 은 형식 일 수도 있다.또한 중용 성에 영향 을 미 칠 수 있 는 결정 에 대해 우 리 는 이 를 다른 대상 류 에 맡 길 수 있다.즉,delegate 를 통 해 일부 업 무 를 분산 시 켜 서 류 의 중용 성 을 더욱 높 일 수 있다.그래서 OC 라 는 언어 는 그리 간단 하지 않다.한 가지 유형 을 잘 설계 하려 면 여러 가지 고려 가 필요 하 다.

좋은 웹페이지 즐겨찾기