[objective-c] Objective-c에서 “인스턴스 변수”와 “속성”간에 차이가 있습니까?

Objective-c에서 “인스턴스 변수”와 “속성”사이에 차이가 있습니까?

나는 이것에 대해 잘 모르겠습니다. “속성”은 접근 자 메서드가있는 인스턴스 변수라고 생각하지만 잘못 생각할 수 있습니다.



답변

속성은 좀 더 추상적 인 개념입니다. 인스턴스 변수는 말 그대로 구조체의 슬롯과 같은 저장소 슬롯입니다. 일반적으로 다른 개체는 직접 액세스 할 수 없습니다. 반면 속성은 액세스 할 수있는 객체의 속성입니다 (모호하게 들리며 그래야합니다). 일반적으로 속성은 인스턴스 변수를 반환하거나 설정하지만 여러 데이터를 사용하거나 전혀 사용하지 않을 수 있습니다. 예를 들면 :

@interface Person : NSObject {
    NSString *name;
}

    @property(copy) NSString *name;
    @property(copy) NSString *firstName;
    @property(copy) NSString *lastName;
@end

@implementation Person
    @synthesize name;

    - (NSString *)firstName {
        [[name componentsSeparatedByString:@" "] objectAtIndex:0];
    }
    - (NSString *)lastName {
        [[name componentsSeparatedByString:@" "] lastObject];
    }
    - (NSString *)setFirstName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
    - (NSString *)setLastName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
@end

(참고 : 위의 코드는 이름이 이미 존재하고 최소한 두 개의 구성 요소 (예 : “Gates”가 아닌 “Bill Gates”)가 있다고 가정한다는 점에서 버그가 있습니다. 이러한 가정을 수정하면 코드의 실제 포인트가 될 것이라고 생각했습니다. 덜 명확하므로 여기에서 지적하고 있으므로 아무도 이러한 실수를 순진하게 반복하지 않습니다.)


답변

속성은 유용한 기능과 구문을 추가하여 일부 값에 대해 getter / setter를 구현하는 친숙한 방법입니다. 속성은 인스턴스 변수에 의해 지원 될 수 있지만 좀 더 동적 인 작업을 수행하기 위해 getter / setter를 정의 할 수도 있습니다. 예를 들어 일부 멤버의 값을 반환하는 대신 결과를 동적으로 생성하는 문자열에 lowerCase 속성을 정의 할 수 있습니다. 변하기 쉬운.

예를 들면 다음과 같습니다.

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;

@property줄은 propertyName유형 이라는 속성을 정의합니다 NSString *. 다음 구문을 사용하여 가져 오거나 설정할 수 있습니다.

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);

할당하거나 읽을 때 myObject.propertyName실제로 개체에 대한 setter / getter 메서드를 호출합니다.

@synthesize줄은 값을 저장하기 위해 속성과 동일한 이름을 가진 멤버 변수 otherVarName를 사용하여 (또는 주석에 구문을 사용하는 경우) 이러한 getter / setter를 생성하도록 컴파일러에 지시합니다 .

함께 @synthesize자신을 정의하여 getter / setter 중 하나를 재정의 할 수 있습니다. 이러한 메서드의 명명 규칙 setPropertyName:은 setter 및 getter에 대한 propertyName(또는 getPropertyName표준이 아님)입니다. 다른 하나는 여전히 생성됩니다.

당신에 @property선 당신은 스레드 안전성 및 메모리 관리 등을 자동화 할 수있는 속성에 대한 괄호에있는 속성의 수를 정의 할 수 있습니다. 기본적으로 속성은 원자 적입니다. 즉, 컴파일러는 @synthesiz동시성 문제를 방지하기 위해 적절한 잠금으로 ed get / set 호출을 래핑 합니다. nonatomic이를 비활성화 하는 속성을 지정할 수 있습니다 (예 : 대부분의 속성을 기본값으로 설정하려는 iPhone nonatomic).

모든 @synthesizedsetter에 대한 메모리 관리를 제어하는 ​​3 개의 속성 값이 있습니다. 첫 번째는 속성의 이전 값과 새 값 retain으로 자동으로 전송 됩니다. 이것은 매우 유용합니다.releaseretain

두 번째는 copy전달 된 값을 유지하지 않고 복사하는 것입니다. copy호출자가 NSMutableString을 전달하고 아래에서 변경할 수 있기 때문에 NSString 을 사용 하는 것이 좋습니다 . copy사용자 만 액세스 할 수있는 입력의 새 사본을 만듭니다.

세 번째는 assign이전 또는 새 개체에 대해 유지 / 해제를 호출하지 않고 직선 포인터 할당을 수행하는 것입니다.

마지막으로 readonly속성을 사용하여 속성에 대한 setter를 비활성화 할 수도 있습니다 .


답변

인터페이스 부분에 대한 속성을 사용합니다. 개체가 다른 개체 및 인스턴스 변수와 인터페이스하는 것은 클래스 내에서 필요한 것입니다.하지만 아무도보고 조작해야합니다.


답변

기본적으로 readwrite 속성은 인스턴스 변수에 의해 지원되며 컴파일러에 의해 자동으로 다시 합성됩니다.

인스턴스 변수는 존재하고 객체의 수명 동안 그 값을 보유하는 변수입니다. 인스턴스 변수에 사용되는 메모리는 객체가 처음 생성 될 때 (할당을 통해) 할당되고 객체가 할당 해제되면 해제됩니다.

달리 지정하지 않는 한 합성 된 인스턴스 변수의 이름은 속성과 동일하지만 밑줄 접두사가 있습니다. 예를 들어 firstName이라는 속성의 경우 합성 된 인스턴스 변수는 _firstName이됩니다.


답변

이전에는 사람들이 속성을 공개적으로 사용하고 ivars를 개인 용도로 사용했지만 몇 년 전부터 속성을 정의 @implementation하여 비공개로 사용할 수도 있습니다. 그러나 입력 할 문자가 적고이 기사 에 따라 더 빠르게 실행되므로 가능하면 ivars를 계속 사용합니다 . 속성은 “무거움”을 의미하기 때문에 의미가 있습니다. 생성 된 getter / setter 또는 수동으로 작성된 것에서 액세스해야합니다.

그러나 Apple의 최근 코드에서는 ivar가 더 이상 사용되지 않습니다. 더 같이이기 때문에 추측 objc이 아니라 C/C++, 그것 플러스와 속성을 사용하는 것이 더 쉽습니다 assign, nullable


답변