52개의 유효한 방법(7) - 대상 내부에서 가능한 한 실례 변수에 직접 접근

4282 단어

대상 내부에서 가능한 한 실례 변수에 직접 접근하다


대상 내부에서 데이터를 읽을 때는 실례 변수를 통해 직접 읽어야 하고, 데이터를 쓸 때는 속성을 통해 써야 한다.
  • _name = @"Jack"setter의 메시지를 거치지 않고 변수에 직접 값을 부여하여 속도가 빠르다.다음name 속성에 대해: @property (nonatomic, copy) NSString *name; 직접 할당값은: _name = @"Jack";통과self.name = @"Jack"는 사실_name = @"Jack".copy과 같다.
  • self.name = @"Jack"는 KVO를 터치하고, _name = @"Jack"는 하지 않습니다. - self.name = @"Jack"setter 방법에서 단점 디버깅을 할 수 있습니다. 매번 값을 부여할 때마다 알 수 있습니다.
  • 그래서 합리적인 절충 방안은 데이터를 읽을 때NSString *str = _name, 부치용self.name = @"Jack"이다.

  • 대상 내부에서 실례 변수를 방문할 때 속성(self.proper을 통해 방문하느냐 _proper을 통해 방문하느냐는 속성을 집행하느냐setter, getter 방법에 따라 다르다.
  • 속성의 setter, getter 방법을 실행하면 _proper를 통해 접근합니다.
  • 속성의 setter, getter 방법이 실행되지 않으면 속성self.proper을 통해 접근합니다.
  • @interface Wrestler : NSObject
     
    @property (copy, nonatomic) NSString *name; //  name 
     
    - (void)smell;
     
    @end
     
    @implementation Wrestler
    @synthesize name = _name; //  name _name 
     
    - (void)setName:(NSString *)aName {
        NSLog(@"Set name");
        _name = [aName copy];
    }
     
    - (NSString *)name {
        NSLog(@"Get name");
        return [_name copy];
    }
    - (void)smell {
        NSLog(@"*** Smelling ***");
        
        //  dot syntax 
        NSLog(@"%@", self.name);
        
        //  getter 
        NSLog(@"%@", [self name]);

    초기화 방법 및 dealloc 방법에서는 항상 실례 변수를 통해 데이터를 직접 읽어야 한다.
  • 자류는 복사할 수 있다setter 방법은 self.proper = @""와 같지 않을 수 있다_proper = @"".copy.
  • 우리는 Wrestler의 하위 클래스Cena를 썼다. 이 클래스는 속성name을 계승하고 그 setter 방법을 다시 썼다. 이 방법은 먼저 이름 접미사가 Cena인지 확인하고 그렇지 않으면 이상을 던진다.
  • @interface Cena : Wrestler
     
    - (instancetype)initWithName:(NSString *)aName;
     
    - (void)wrestle;
     
    @end
     
    @implementation Cena
    @synthesize name = _name;
     
    - (instancetype)initWithName:(NSString *)aName {
        self = [super init];
        
        if (self) {
            NSLog(@"self.name = aName");
            self.name = aName;
        }
        
        return self;
    }
     
    - (void)wrestle {
        NSLog(@"I'm %@, U can't see me", self.name);
    }
     
    - (void)setName:(NSString *)aName {
        if (![aName hasSuffix:@"Cena"]) {
            [NSException raise:NSInvalidArgumentException format:@"last name must be Cena"];
        }
        
        _name = [aName copy];
    }
     
    @end
  • 부모 Wrestler의 init 방법에서name을 공백 문자열로 초기화@ "
  •  (instancetype)init {
        self = [super init];
        
        if (self) {
            NSLog(@"self.name = empty string");
            self.name = @"";
        }
        
        return self;
  • 호출
  •         Cena *cena = [[Cena alloc] initWithName:@"John Cena"];
            [cena wrestle];
  • 운행이 붕괴되었습니다.원인: self.name = @"";.하위 클래스에 덧붙인 name 방법 setter 을 호출하면 공백 문자열에 @"Cena" 접두사가 뚜렷하게 없어서 이상을 던집니다.
  • Lazy Initialization 설정된 데이터를 사용하면 속성을 통해 데이터를 읽어야 합니다.
    
    @property (strong, nonatomic) NSNumber *chamCount;
    - (NSNumber *)chamCount {
        if (!_chamCount) {
            _chamCount = @13;
        }
        
        return _chamCount;
    

    setter/getter 방법에서 호출하지 마십시오 setter/getter 방법
  • 위의 setter 방법을 수정합니다:
  • - (void)setName:(NSString *)aName {
        NSLog(@"Set name");
    //    _name = [aName copy];
        self.name = aName;
    }
  • 프로그램이 실행되고 컨트롤러가 끊임없이 출력Set name되며 붕괴됩니다.
  • 원인: setter방법에서setter방법을 호출하면 끊임없이 끼워 넣고 호출하여 프로그램이 붕괴됩니다.Getter 방법은 같은 이치이다.

  • 요점

  • 대상 내부에서 데이터를 읽을 때는 실례 변수를 통해 직접 읽어야 하고 데이터를 쓸 때는 속성을 통해 써야 한다.
  • 초기화 방법과 dealloc 방법에서는 항상 실례 변수를 통해 데이터를 직접 읽어야 한다.
  • Lazy Initialization으로 구성된 데이터는 속성을 통해 읽어야 합니다.
  • setter/getter 방법에서 setter/getter 방법을 사용하지 마십시오.
  • 좋은 웹페이지 즐겨찾기