Objective-C'de “@private” ne anlama geliyor?


Yanıtlar:


186

Bu bir görünürlük değiştiricidir - bildirilen örnek değişkenlerine @privateyalnızca aynı sınıfın örnekleri tarafından erişilebileceği anlamına gelir . Özel üyelere alt sınıflar veya diğer sınıflar tarafından erişilemez.

Örneğin:

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

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

Ayrıca açıklığa kavuşturmak için yöntemler Objective-C'de her zaman herkese açıktır. Bununla birlikte, yöntem bildirimlerini "gizlemenin" yolları vardır - daha fazla bilgi için bu soruya bakın .


@Uygulamadan sonra parantez içindeki örnek değişkenler ne olacak? Her zaman özel mi?
John Henckel

Eski olduğunu biliyorum ... Ama görünürlük değiştirici değil. Bir erişim değiştiricidir. C ++ 'da daha önemli bir ayrımdır, ancak Objective-C'de de bir ayrımdır. Değişken derleyici tarafından görülebilir. Derleyici erişmenize izin vermiyor.
gnasher729

161

Htw'nin dediği gibi, bu bir görünürlük değiştiricisidir. @privateivar'a (örnek değişkeni) yalnızca aynı sınıfın bir örneğinden doğrudan erişilebileceği anlamına gelir. Ancak, bu sizin için çok önemli olmayabilir, bu yüzden size bir örnek vereyim. initBasitlik adına sınıfların yöntemlerini örnek olarak kullanacağız . İlgilenilen öğeleri belirtmek için satır içi yorum yapacağım.

@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;
}

Sorunuzu cevaplamak için @private, ivar'ları başka bir sınıfın örneğiyle erişime karşı korur. İki MyFirstClass örneğinin, birbirlerinin tüm ivarlarına doğrudan erişebileceğini unutmayın; programcı bu sınıf üzerinde doğrudan tam kontrol sahibi olduğu için bu yeteneği akıllıca kullanacağı varsayılmaktadır.


20
Objective-C'de @public, @proteced ve @private kullanmanın yaygın olmadığı belirtilmelidir. Tercih edilen yaklaşım her zaman erişimcileri kullanmaktır.
Georg Schölly

1
@Georg, ancak ivarlarınızı sınırlı görünürlükle işaretlemediğiniz sürece erişimcilerin kullanımını nasıl zorlarsınız?
Greg Maletic

5
@Georg Schölly: xcode 4.x + @privatebir nesnenin şablonunu otomatik olarak koyduğundan , artık çok nadir değildir.
dawg

1
@Georg Bence @private, @protected mirasın söz konusu olduğu durumlarda kullanılabilir, kişisel olarak kullanmadım :)
chunkyguy

5
Bu günlerde, kamu değişkenine örnek değişkenleri koymak için çok az neden olduğu belirtilmelidir. Doğrudan @implementationblok üzerine yerleştirilebilirler . Bunu yaptıktan sonra, görünürlük değiştiricileri ne olursa olsun etkili bir şekilde gizlidirler, çünkü bu dosyanın dışındaki kişiler tarafından bile görülemezler.
BJ Homer

14

Birisi bir @privateörnek değişkenine erişemeyeceğinizi söylediğinde bunun ne anlama geldiğini anlamak önemlidir . Gerçek hikaye, kaynak kodunuzda bu değişkenlere erişmeye çalıştığınızda derleyicinin size bir hata vermesidir. GCC ve XCode'un önceki sürümlerinde, hata yerine bir uyarı alırsınız.

Her iki durumda da, çalışma zamanında tüm bahisler kapalıdır. Bunlara @privateve @protectedivarlara herhangi bir sınıftaki bir nesne tarafından erişilebilir. Bu görünürlük değiştiricileri, kaynak kodunu görünürlük değiştiricilerinin amacını ihlal eden makine koduna derlemeyi zorlaştırır.

Güvenlik için ivar görünürlük değiştiricilerine güvenmeyin! Hiçbir şey sağlamazlar. Kesinlikle sınıf kurucusunun isteklerinin derleme zamanında uygulanması içindir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.