Objective-C에서“@private”은 무엇을 의미합니까?


답변:


186

그것은 A의 가시성 수정 인스턴스 변수로 선언 - 그것은 수단 것을 @private에만 액세스 할 수 있습니다 같은 클래스의 인스턴스 . 서브 클래스 또는 다른 클래스는 개인 멤버에 액세스 할 수 없습니다.

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

@interface MyClass : NSObject
{
    @private
    int someVar;  // Can only be accessed by instances of MyClass

    @public
    int aPublicVar;  // Can be accessed by any object
}
@end

또한 명확히하기 위해 메소드는 항상 Objective-C에서 공개됩니다. 메서드 선언을 "숨기는"방법 있습니다. 자세한 내용 은 이 질문 을 참조하십시오.


@implementation 후 중괄호 안에있는 인스턴스 변수는 어떻습니까? 그들은 항상 개인입니까?
John Henckel

나는 그것이 오래되었다는 것을 알고 있습니다 ...하지만 가시성 수정자는 아닙니다. 액세스 수정 자입니다. C ++에서 더 중요한 차이점이지만 Objective-C에서도 구별됩니다. 변수는 컴파일러에서 볼 수 있습니다. 컴파일러는 액세스 할 수 없습니다.
gnasher729

161

htw가 말했듯이 가시성 수정 자입니다. @private즉, ivar (인스턴스 변수)는 동일한 클래스의 인스턴스 내에서만 직접 액세스 할 수 있습니다. 그러나 이는 그다지 의미가 없을 수 있으므로 예를 들어 보겠습니다. init단순화를 위해 클래스 의 메소드를 예제로 사용합니다 . 관심있는 항목을 지적하기 위해 인라인으로 댓글을 달겠습니다.

@interface MyFirstClass : NSObject
{
    @public
    int publicNumber;

    @protected  // Protected is the default
    char protectedLetter;

    @private
    BOOL privateBool;
}
@end

@implementation MyFirstClass
- (id)init {
    if (self = [super init]) {
        publicNumber = 3;
        protectedLetter = 'Q';
        privateBool = NO;
    }
    return self;
}
@end

@interface MySecondClass : MyFirstClass  // Note the inheritance
{
    @private
    double secondClassCitizen;
}
@end

@implementation MySecondClass
- (id)init {
    if (self = [super init]) {
        // We can access publicNumber because it's public;
        // ANYONE can access it.
        publicNumber = 5;

        // We can access protectedLetter because it's protected
        // and it is declared by a superclass; @protected variables
        // are available to subclasses.
        protectedLetter = 'z';

        // We can't access privateBool because it's private;
        // only methods of the class that declared privateBool
        // can use it
        privateBool = NO;  // COMPILER ERROR HERE

        // We can access secondClassCitizen directly because we 
        // declared it; even though it's private, we can get it.
        secondClassCitizen = 5.2;  
    }
    return self;
}

@interface SomeOtherClass : NSObject
{
    MySecondClass *other;
}
@end

@implementation SomeOtherClass
- (id)init {
    if (self = [super init]) {
        other = [[MySecondClass alloc] init];

        // Neither MyFirstClass nor MySecondClass provided any 
        // accessor methods, so if we're going to access any ivars
        // we'll have to do it directly, like this:
        other->publicNumber = 42;

        // If we try to use direct access on any other ivars,
        // the compiler won't let us
        other->protectedLetter = 'M';     // COMPILER ERROR HERE
        other->privateBool = YES;         // COMPILER ERROR HERE
        other->secondClassCitizen = 1.2;  // COMPILER ERROR HERE
    }
    return self;
}

따라서 귀하의 질문에 대답하기 위해 @private는 다른 클래스의 인스턴스가 ivar을 액세스하지 못하도록 보호합니다. MyFirstClass의 두 인스턴스는 서로의 모든 ivar에 직접 액세스 할 수 있습니다. 프로그래머가이 클래스를 직접 완벽하게 제어 할 수 있기 때문에이 기능을 현명하게 사용할 것입니다.


20
Objective-C에서 @public, @proteced 및 @private를 사용하는 것은 일반적이지 않습니다. 선호되는 접근 방식은 항상 접근자를 사용하는 것입니다.
Georg Schölly

1
@Georg, 그러나 ivar에 제한된 가시성을 표시하지 않는 한 접근자를 사용하려면 어떻게해야합니까?
Greg Maletic

5
@Georg Schölly : xcode 4.x +는 자동으로 @private객체의 템플릿을 넣으 므로 더 이상 그렇게 드물지 않습니다.
dawg

1
@Georg @private, @protected는 상속이 관련된 경우에 사용할 수 있다고 생각하지만 개인적으로 사용하지는 않았습니다 :)
chunkyguy

5
요즘에는 인스턴스 변수를 퍼블릭 헤더에 넣을 이유가 거의 없습니다. 그들은 @implementation블록 에 직접 놓을 수 있습니다 . 그리고 일단 그렇게하면 가시성 수정 자에 관계없이 효과적으로 비공개로 유지됩니다. 파일 외부의 누구도 볼 수 없기 때문입니다.
BJ 호머

14

누군가가 @private인스턴스 변수에 액세스 할 수 없다고 말할 때의 의미를 이해하는 것이 중요 합니다. 실제로 소스 코드에서 이러한 변수에 액세스하려고하면 컴파일러에서 오류가 발생합니다. 이전 버전의 GCC 및 XCode에서는 오류 대신 경고가 표시됩니다.

어느 쪽이든, 런타임에 모든 베팅이 해제됩니다. 이 클래스 @private@protectedivar은 모든 클래스의 객체로 액세스 할 수 있습니다. 이러한 가시성 수정자는 가시성 수정 자의 의도를 위반하는 머신 코드로 소스 코드를 컴파일하기 어렵게 만듭니다.

보안을 위해 ivar 가시성 수정 자에 의존하지 마십시오! 그들은 전혀 제공하지 않습니다. 그들은 클래스 빌더의 소원을 컴파일 타임으로 시행하기위한 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.