2013-03-26 4 views
2

У меня есть 2 класса, которые я хочу иметь доступ к свойствам других объектов, но я не хочу, чтобы эти свойства были доступны из любого места. Есть ли способ сделать это? Это единственный способ добиться этого путем подкласса? Нет ли способа установить «особые» отношения между двумя классами?Есть ли способ разрешить некоторым классам доступ к приватным свойствам некоторых других классов?

ответ

12

Если я понимаю ваш вопрос, вы действительно хотите, чтобы класс A и класс B, не связанные между собой наследованием, были осведомлены о более внутренних вещах, чем публично рекламируются?

Скажите, что A имеет свойство innardsForB, к которому должны обращаться только экземпляры B. Вы можете использовать расширение класса объявить непубличный интерфейс А.


Ах

@interface A:NSObject 
... regular class goop here ... 
@end 


A-Private.h

@interface A() 
@property(nonatomic, strong) Innards *innardsForB; 
@end 


Am

#import "A.h" 
#import "A-Private.h" 

@implementation A 
// because "A-Private.h" is #import'd, `innardsForB` will be automatically @synthesized 
... 
@end 


B.m

#import "B.h" 
#import "A-Private.h" 

@implementation B 
... 
- (void)someMethod 
{ 
    A *a = [self someASomewhere]; 
    a.innardsForB = [[Innards alloc] initForMeaning:@(42)]; 
} 
+0

В этом примере A-Private.h является расширением класса? – zakdances

+2

Исправить; '@interface A()' является расширением класса. Это означает «расширить класс A, чтобы он имел этот дополнительный набор объявлений». Пока это расширение видимо компилятору при компиляции '@ implementation', все объявления в расширении ведут себя так же, как они были объявлены в интерфейсе' @ 'класса. – bbum

3

Протоколы предназначены для этой цели. Вы не можете остановить сторонние классы от реализации или использования протокола. Методы внутри них являются общедоступными, но не обязательно частью открытого интерфейса.

-8

на Obj-C свойства защищены. Это означает, что вы можете только присоединяться к свойствам по наследству.

@interface A : NSObject{ 
    NSObject* prop; 
} 
@end 

@implementation A 
@end 

@interface B : A 
@end 

@implementation B 
- (void)protected{ 
    self->prop; // yep 
} 
@end 

@interface XXX : NSObject 
@end 

@implementation XXX 

- (void)test{ 
    A* a = [[A alloc] init]; 
    a->prop; // wrong, will not compile 
} 

@end 

Если вы хотите получить доступ к скрытым свойствам посредством метода, вы можете использовать просто категорию, скрытую в реализации, или мост. Но нет никакого способа установить «особые» отношения между двумя классами. Но вы можете обеспечить соблюдение этих отношений с вашим дизайном кода.

+7

Там нет свойств в коде и использование '->' влезает инкапсуляции. – bbum

+0

bbum, вы должны узнать, что такое свойства. –

+2

'prop' - это переменная экземпляра, которая немного отличается от свойства, которое имеет очень специфическое значение в ObjC.Использование категории для доступа к «скрытым» функциям в другом классе - плохое предложение; расширения класса были созданы именно для решения этой проблемы, как я изложил в своем ответе, и он служит для создания именно таких «специальных» отношений. – bbum

-1

Я хочу, чтобы свойства класса classB класса classA и classC не просто отображали ссылку класса A в ClassB и не объявляли его в ClassB.

Пример:

@interface ClassA 
@property (nonatomic, strong) UILabel *label1; 
@end 

#import "ClassB.h" 
#import "ClassA.h" // To access public properties and all methods declared in ClassA.h 

@implementation ClassB 

ClassA *classA = ....; 
classA.label1.text = ...; 

@end 

Из этого примера, ClassB может получить доступ ко всем общественным (объявленная в CalssA.h) proerties и методы ClassA.

Вы также можете использовать делегат для этого.

+0

Это дублирование информации, которое приводит к хрупкости всей вашей кодовой базы. Теперь вы должны помнить, что всегда выполняйте поиск кода для всех повторных объявлений каждого свойства, если он был дублирован в другом месте. – bbum