Свойства только для класса и его подклассов

Можно ли определить свойства, доступные только для класса, в котором они определены, и подклассов этого класса?

Другими словами, есть ли способ определить защищенные свойства?

20 голосов | спросил Jay Haase 24 32010vEurope/Moscow11bEurope/MoscowWed, 24 Nov 2010 10:09:27 +0300 2010, 10:09:27

3 ответа


0

Технически, нет. Свойства на самом деле являются просто методами, и все методы общедоступны. Способ, которым мы «защищаем» методы в Objective-C, заключается в том, чтобы не сообщать о них другим людям.

Практически да. Вы можете определить свойства в расширении класса, и все же @synthesize их в основном блоке реализации.

ответил Dave DeLong 24 32010vEurope/Moscow11bEurope/MoscowWed, 24 Nov 2010 10:16:56 +0300 2010, 10:16:56
0

Это возможно с помощью расширения класса (не категории), которое вы включаете в файлы реализации базового класса и подклассов.

Расширение класса определяется аналогично категории, но без имени категории:

@interface MyClass ()

В расширении класса вы можете объявить свойства, которые будут в состоянии синтезировать вспомогательные ivars (XCode> 4.4 автоматический синтез ivars также работает здесь).

В классе расширений вы можете переопределить /уточнить свойства (изменить только чтение на чтение и т. д.) и добавить свойства и методы, которые будут «видны» файлам реализации (но обратите внимание, что свойства и методы на самом деле частный и все еще может быть вызван селектором).

Другие предложили использовать для этого отдельный заголовочный файл MyClass_protected.h, но это также можно сделать в основном заголовочном файле, используя #ifdef вот так:

Пример:

BaseClass.h

@interface BaseClass : NSObject

// foo is readonly for consumers of the class
@property (nonatomic, readonly) NSString *foo;

@end


#ifdef BaseClass_protected

// this is the class extension, where you define 
// the "protected" properties and methods of the class

@interface BaseClass ()

// foo is now readwrite
@property (nonatomic, readwrite) NSString *foo;

// bar is visible to implementation of subclasses
@property (nonatomic, readwrite) int bar;

-(void)baz;

@end

#endif

BaseClass.m

// this will import BaseClass.h
// with BaseClass_protected defined,
// so it will also get the protected class extension

#define BaseClass_protected
#import "BaseClass.h"

@implementation BaseClass

-(void)baz {
    self.foo = @"test";
    self.bar = 123;
}

@end

ChildClass.h

// this will import BaseClass.h without the class extension

#import "BaseClass.h"

@interface ChildClass : BaseClass

-(void)test;

@end

ChildClass.m

// this will implicitly import BaseClass.h from ChildClass.h,
// with BaseClass_protected defined,
// so it will also get the protected class extension

#define BaseClass_protected 
#import "ChildClass.h"

@implementation ChildClass

-(void)test {
    self.foo = @"test";
    self.bar = 123;

    [self baz];
}

@end

Когда вы вызываете #import, он в основном копирует и вставляет файл .h туда, куда вы его импортируете. Если у вас есть #ifdef, он будет включать в себя код, только если #define с этим именем установлено.

В вашем .h файле вы не устанавливаете определение, поэтому любые классы, импортирующие этот .h, не увидят расширение защищенного класса. В файле базового класса и подкласса .m вы используете #define перед использованием #import, чтобы компилятор включал расширение защищенного класса.

ответил d4n3 6 FebruaryEurope/MoscowbThu, 06 Feb 2014 19:51:51 +0400000000pmThu, 06 Feb 2014 19:51:51 +040014 2014, 19:51:51
0

Вы можете использовать такой синтаксис в реализации подкласса.

@interface SuperClass (Internal)

@property (retain, nonatomic) NSString *protectedString;

@end
ответил Arietis 12 Jpm1000000pmSat, 12 Jan 2013 15:34:49 +040013 2013, 15:34:49

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132