예 를 들 어 Objective-C 에서@property 속성의 용법 을 설명 합 니 다.

11190 단어 Objective-C
c/c++를 배 운 친구 들 은 모두 알 고 있 습 니 다.우리 가 struct/class 를 정의 할 때 방문 한정 자(Public,proctected,private)를 Public 로 설정 하면 우 리 는 직접.번 호 를 사용 하여 내부 의 데이터 구성원 을 방문 할 수 있 습 니 다.예 를 들 면

//in Test.h
class Test
{
public:
  int i;
  float f;
};

저 는 main 함수 에서 다음 과 같은 방식 으로 이 종 류 를 사용 할 수 있 습 니 다.(주의,main 함수 에서 이런 종 류 를 사용 하면 헤더 파일 을 포함 하 는 것 을 제외 하고 가장 중요 한 것 은 main.m 를 main.mm 로 바 꾸 는 것 입 니 다.그렇지 않 으 면 이상 한 오 류 를 보고 할 수 있 습 니 다.따라서 언제든지 c++를 사용 합 니 다.이상 한 오 류 를 보고 하면 해당 원본 파일 을.mm 접미사 로 바 꾸 었 는 지 알려 야 합 니 다.다른 인용 파일 도 가끔.mm 파일 로 바 꿔 야 합 니 다)

  //in main.mm
  Test test;
  test.i =1;
  test.f =2.4f;
  
  NSLog(@"Test.i = %d, Test.f = %f",test.i, test.f);
그런데 obbc 에서 우리 가 이렇게 할 수 있 을까요?다음 코드 를 보십시오.(obbc 클래스 를 새로 만 들 고 BaseClass 라 고 명명 합 니 다)

//in BaseClass.h
@interface BaseClass : NSObject{
@public
    NSString *_name;
}
다음,우 리 는 main.mm 안에 있 습 니 다.

    BaseClass *base= [[BaseClass alloc] init];
    base.name =@"set base name";
    NSLog(@"base class's name = %@", base.name);
   
컴 파일 을 기다 리 지 않 아 도 됩 니 다.xcode 에서 바로 오 류 를 알 립 니 다.캡 처 를 보십시오.
201632591128870.jpg (700×100)
오류 알림"Property'nam'not found on object of type BaseClass*"를 주의 하 세 요.BaseClass 같은 종 류 는 name 이라는 속성 이 하나 도 없다 는 뜻 입 니 다.비록 우리 가 헤더 파일 에서@Public 를 성명 하 더 라 도,우 리 는 BaseClass 를 사용 할 때,데이터 구성원 에 게 직접 접근 할 수 없습니다.한편,@public,@proctected 와@private 는 클래스 를 계승 하 는 접근 권한 에 만 영향 을 줄 수 있 습 니 다.@private 를 사용 하면 하위 클래스 에 서 는 부모 클래스 의 개인 구성원 을 직접 사용 할 수 없습니다.이것 은 c+,자바 와 같 습 니 다.
오류 가 있 으 면 해결 할 방법 을 생각해 보 겠 습 니 다.컴 파일 러 가@property 가 없다 고 했 습 니 다.좋 습 니 다.property 를 정의 하 겠 습 니 다.코드 를 보 세 요.

//in BaseClass.h
@interface BaseClass : NSObject{
@public
    NSString *_name;
}
@property(nonatomic,copy) NSString *name;
//in BaseClass.m
@synthesize name = _name;
현재,컴 파일 및 실행,ok,좋 습 니 다.그럼@prperty 에 게 물 어 보 셨 을 수도 있 습 니 다.@property 만 정의 하면..번 호 를 사용 하여 클래스 의 데이터 멤버 를 방문 할 수 있 습 니까?먼저 다음 의 예 를 살 펴 보 자.

@interface BaseClass : NSObject{
@public
    NSString *_name;
}
//@property(nonatomic,copy) NSString *name;

-(NSString*) name;
-(void) setName:(NSString*)newName;

@property 의 정의 주석 을 지 웠 습 니 다.두 함수,name 과 setName 을 정 의 했 습 니 다.다음은 실행 파일 을 보십시오.

//@synthesize name = _name;

-(NSString*) name{
    return _name;
}

-(void) setName:(NSString *)name{
    if (_name != name) {
        [_name release];
        _name = [name copy];
    }
}

지금,당신 은 다시 컴 파일 하여 운행 합 니 다.똑 같이 일 을 잘 합 니 다.why?내 가 방금 한 일 은 이전에 성명 한@property 가 한 일과 완전히 같 기 때문이다.@prperty 는 컴 파일 러 에 게 보 여 주 는 명령 일 뿐 컴 파일 한 후에 해당 하 는 getter 와 setter 방법 을 만 들 수 있 습 니 다.그리고 면 property(nonatomic,copy)괄호 안에 있 는 이 copy 인 자 를 보 았 습 니까?그것 이 한 일 은 바로

_name = [name copy];
   retain, assign, :

//property(retain)NSString* name;
_name = [name retain];

//property(assign)NSString* name;
_name = name;

다른 것 은 여기까지 입 니 다.@property 는 getter 와 setter 방법 만 생 성 할 수 있 는 것 이 아니 라 메모리 관리 도 할 수 있 습 니 다.하지만 여 기 는 잠시 논의 하지 않 겠 습 니 다.지금@property 에서 무슨 일 을 했 는 지 이미 알 고 있 을 겁 니 다.그러나 우리 프로그래머 들 은 모두 자신 이 완전히 먹 은 것 이 없고 마음 이 든든 하지 않다 는 것 이다.특히 나 나 자신 이다.그래서 다음은@property 의 모든 디 테 일 을 자세히 파 야 합 니 다.
먼저,우 리 는 atomic 와 nonatomic 의 차이 와 용법 을 봅 니 다.말 하기 전에 다음 코드 를 먼저 봅 니 다.

@property(nonatomic, retain) UITextField *userName;    //1

@property(nonatomic, retain,readwrite) UITextField *userName;  //2

@property(atomic, retain) UITextField *userName;  //3

@property(retain) UITextField *userName;  //4

@property(atomic,assign) int i;         // 5

@property(atomic) int i;         //6
@property int i;               //7

독자 들 은 먼저 멈 춰 서서 생각해 보 세 요.그것들 은 어떤 차이 가 있 습 니까?
위의 코드 1 과 2 는 등가 이 고 3 과 4 는 등가 이 며 5,6,7 은 등가 이다.즉,atomic 는 기본 행동 이 고 assign 은 기본 행동 이 며 readwrite 는 기본 행동 입 니 다.하지만@property(nontomic)NSString*name 을 쓰 면;그러면 다음 과 같은 경 고 를 보 내 드 리 겠 습 니 다.
201632591159602.jpg (700×50)
gc 가 아 닌 대상 이기 때문에 기본 assign 수식 자 는 안 됩 니 다.그럼 언제 assign,언제 retain,copy 를 사용 합 니까?추천 방법 은 NSString 용 copy,delegate 용 assign(그리고 assign 을 사용 해 야 합 니 다.왜 냐 고 묻 지 말고 사용 하면 됩 니 다.나중에 알 게 될 것 입 니 다)입 니 다.예 를 들 어 int,float 등 기본 데이터 형식 은 assign(기본 값 은 assign)을 사용 하고 다른 obsc 형식,예 를 들 어 NSArray,NSDate 는 retain 을 사용 합 니 다.
계속 하기 전에 저 는 몇 가지 문 제 를 보충 하고 싶 습 니 다.만약 에 우리 가 특정한 변수의 setter 방법 을 정의 한다 면 컴 파일 러 가 우리 에 게 getter 방법 을 만들어 주 고 싶 습 니 다.이렇게 하면 되 겠 습 니까?답 은 당연 하지.만약 당신 이.m 파일 에서 setter/getter 방법 을 실현 했다 면,번역기 로 더 이상 getter/setter 를 만 들 지 않 았 을 것 입 니 다.다음 코드 를 보십시오.

// :
@interface BaseClass : NSObject{
@public
    NSString *_name;
}
@property(nonatomic,copy,readonly) NSString *name;  // readonly, geter

-(void) setName:(NSString*)newName;

// :
@interface BaseClass : NSObject{
@public
    NSString *_name;
}
@property(nonatomic,copy,readonly) NSString *name;   // readonly, getter , getter 。

-(NSString*) name;   //getter name ? , Foundation.framework, UIView.h, property )
-(void) setName:(NSString*)newName;

// :
@interface BaseClass : NSObject{
@public
    NSString *_name;
}
@property(nonatomic,copy,readwrite) NSString *name;  // getter setter

// :
@interface BaseClass : NSObject{
@public
    NSString *_name;
}
@property(nonatomic,copy) NSString *name;  // readwrite ,

위의 4 단 코드 는 등가 입 니 다.다음은 아래 4 단 코드 를 보 세 요.

// :
@synthesize name = _name;  // , getter setter, getter setter

// :
@synthesize name = _name;  // name, getter , setter , setName 。

-(NSString*) name{
    NSLog(@"name");
    return _name;
}

// :
@synthesize name = _name;   // setter , getter

-(void) setName:(NSString *)name{
    NSLog(@"setName");
    if (_name != name) {
        [_name release];
        _name = [name copy];
    }
}

// :
@synthesize name = _name;  // getter setter, , 。

-(NSString*) name{
    NSLog(@"name");
    return _name;
}

-(void) setName:(NSString *)name{
    NSLog(@"setName");
    if (_name != name) {
        [_name release];
        _name = [name copy];
    }
}

위의 이 4 단 코드 도 등가 이다.이 를 보면 프로 퍼티 의 역할 에 대해 좀 더 이해 해 주 실 거 라 고 믿 습 니 다.하지만,당신 은 반드시 조심해 야 합 니 다.만약 당신 이 Property 를 사 용 했 고,또 setter/getter 를 다시 썼 다 면,당신 은 도대체 무슨 일 을 했 는 지 똑똑히 알 아야 합 니 다.아래 코드 를 쓰 지 마 세 요.합 법 적 이지 만 다른 사람 을 오도 할 수 있 습 니 다.

//BaseClass.h
@interface BaseClass : NSObject{
@public
    NSArray *_names;
}
@property(nonatomic,assgin,readonly) NSArray *names;  // assign

-(void) setNames:(NSArray*)names;

//BaseClass.m
@implementation BaseClass

@synthesize names = _names;

-(NSArray*) names{
    NSLog(@"names");
    return _names;
}

-(void) setNames:(NSArray*)names{
    NSLog(@"setNames");
    if (_name != name) {
        [_name release];
        _name = [name retain];  // retain, , setNames , assign
    }
}

다른 사람 이@property 를 사용 하여 메모리 관 리 를 할 때 문제 가 생 길 수 있 습 니 다.요약 하면 getter 와 setter 를 실현 했다 면 atomic/nonatomic/retain/assign/copy 는 컴 파일 에 대한 조언 일 뿐 컴 파일 은 먼저 코드 에서 찾 을 것 입 니 다.해당 getter 와 setter 를 정의 했다 면 좋 습 니 다.없 으 면 컴 파일 러 는 atomic/nonatomic/retain/assign/copy 에 따라 지정 한 몇 가지 규칙 에 따라 getter 와 setter 를 생 성 합 니 다.
@property 의 속성 키 워드 를 정리 합 니 다:
1.원자 성 nonatomic/atomic
기본 적 인 상황 에서 컴 파일 러 로 합성 하 는 방법 은 잠 금 체 제 를 통 해 원자 성(atomicity)을 확보 합 니 다.nonatomic 특질 이 있 으 면 동기 잠 금 을 사용 하지 않 습 니 다.
2.읽 기/쓰기 권한  readwrite/readonly
3.메모리 관리 의미
assign'설정 방법'은'순 량 형식'(scalar type,CGFloat 또는 NSInteger 등)에 대한 간단 한 할당 작업 만 수행 합 니 다.
strong"관계 가 있 음"이 속성 에 새 값 을 설정 할 때 설정 방법 은 새 값 을 보류 하고 오래된 값 을 방출 한 다음 에 새 값 을 설정 합 니 다.
weak"비 보유 관계"가 이러한 속성 에 새 값 을 설정 할 때 설정 방법 은 새 값 을 보류 하지 않 을 뿐만 아니 라 오래된 값 도 방출 하지 않 습 니 다.이 특질 은 assign 과 유사 하지만 속성 이 가리 키 는 대상 이 파괴 되면 속성 도 비 워 집 니 다(nil out)
unsafe_unreanted 라 는 특질 적 의 미 는 assign 과 같 지만'대상 유형'(object type)에 적용 된다.이 특질 은'비 보유 관계'('보류 하지 않 음',unreanted)를 표현 하 는데 목표 대상 이 파괴 되 었 을 때 속성 값 이 자동 으로 비 워 지지 않 는 다('불안 전',unsafe)는 점 은 weak 와 차이 가 있다.
copy 라 는 특질 이 표현 하 는 소속 관 계 는 strong 과 유사 하 다.그러나 설정 방법 은 새 값 을 유지 하지 않 고'복사'(copy)합 니 다.
4.방법 명
getter=
@property (nonatomic, getter=isOn) BOOL on;
setter=잘 안 써 요.
총결산
자,이렇게 많이 말 했 으 니 우리 의 본론 으로 돌아 가자.atomic 와 nonatomic 의 역할 과 차이 점:
컴 파일 러 에 코드 를 만 들 려 면@synthesize 를 사용 하 십시오.atomic 와 nonatomic 가 만 든 코드 는 다 릅 니 다.아 토 믹 을 사용 하면 getter 와 setter 의 작업 이 올 바 르 게 실 행 될 것 입 니 다.다른 스 레 드 가 get 에 있 을 때 set 를 걱정 하지 않 아 도 어느 정도 스 레 드 안전 을 보장 할 수 있 습 니 다.그러나 나 는 인터넷 에 접속 하여 자 료 를 찾 아 보 았 는데,단지 atomic 로 라인 의 안전 을 보장 하 는 것 은 매우 천진 하 다.라인 보안 코드 를 쓰 려 면 동기 화 와 상호 배척 메커니즘 이 필요 하 다.
그리고 nonatomic 는 비슷 한'스 레 드 안전'이 없습니다.따라서 nonatomic 는 atomic 보다 속도 가 빠 른 것 이 분명 하 다.이것 도 바로 우리 가 기본적으로 property 를 사용 하 는 모든 곳 은 nonatomic 를 사용 하 는 이유 이다.
그리고 한 가 지 는 독자 들 이 자주 볼 수 있 습 니 다.제 튜 토리 얼 의 dealoc 함수 에 이런 코드 가 있 습 니 다.self.xxx=nil;여기 보 세 요.이제 이렇게 쓰 면 무슨 소 용이 있 는 지 아 시 죠?그것 은[xxx release]와 같다.  xxx = [nil retain];(---만약 당신 의 property(nonatomic,retian)xxx 라면 이렇게 될 것 입 니 다.그렇지 않 으 면 번호 대로 자리 에 앉 으 세 요.
닐 은 오류 가 없 이 모든 메 시 지 를 보 낼 수 있 기 때문이다.왜 release 가 떨 어 졌 는데 도 nil 로 할당 해 야 합 니까?모두 c 를 사용 할 때 이런 인 코딩 습관 이 있 죠?
  int* arr = new int[10];    그리고 사용 하지 않 을 때 delete arr;arr = NULL;  obbc 에 서 는 한 마디 로 self.arr=nil 을 사용 할 수 있 습 니 다.해결 하 다.

좋은 웹페이지 즐겨찾기