Objective c 目标C中的私有v/s公共类属性

Objective c 目标C中的私有v/s公共类属性,objective-c,oop,public,private-members,Objective C,Oop,Public,Private Members,试图使我的OOP基础知识以目标C为基础。如果我的解释太长,对不起。 我在我的应用程序中有3个类,分别为A类、B类和C类目标C类。 在B类的实现中,我有一个a类的属性,即它使B类成为私有属性 // implementation Class B @interface ClassB () @property (nonatomic, strong) ClassA *classA; @end 我在一个C类方法中创建了一个B类的实例,并尝试通过C类中B类的实例访问A类属性 // implementat

试图使我的OOP基础知识以目标C为基础。如果我的解释太长,对不起。 我在我的应用程序中有3个类,分别为A类、B类和C类目标C类。 在B类的实现中,我有一个a类的属性,即它使B类成为私有属性

// implementation Class B
@interface ClassB ()
  @property (nonatomic, strong) ClassA *classA;
@end
我在一个C类方法中创建了一个B类的实例,并尝试通过C类中B类的实例访问A类属性

// implementation Class C
@interface ClassC ()
  @property (nonatomic, strong) ClassB *classB;
@end

@implementation ClassC
- (void)someMethod
{
  NSString *string = [[NSString alloc] init];
  classB = [[ClassB alloc] init];
  string = classB.classA.displayString; //get an error here - ClassB doesn't have classA.
}
@end
为了避免错误,我将classA属性从实现移动到ClassB中的头

// header Class B
@interface ClassB : NSObject
  @property (nonatomic, strong) ClassA *classA;
@end
但我担心任何类都可以创建类B的实例,访问类A属性,然后使用/修改属于类A的属性

问题:将classA属性移动到B类的头文件中,这样我就可以在C类中使用它,这是一种好的方式吗?还是应该在B类中创建一个方法,从a类返回我需要的任何内容?比如:

@implementation ClassB
- (NSString*)displayStringOfClassA
{
  classA = [[ClassA alloc] init];
  return self.classA.displayString;
}
@end
在B.h类中:

@interface ClassB: NSObject
  @property (nonatomic, strong, readonly) ClassA *classA;
@end
在B.m类中:

@interface ClassB()
  @property (nonatomic, strong, readwrite) ClassA *classA;
@end
另外,
strong
readwrite
是默认的修饰符-您可以去掉它们。但是,它们提高了代码的可读性。
编辑:如果您想禁止对ClassA属性的访问,请使用相同的技巧。建议上述代码将禁止仅修改classB的classA属性。对于ClassA的显示字符串:
在A.h类中:

@interface ClassA: NSObject
  @property (nonatomic, strong, readonly) NSString *displayString;
@end
在ClassA.m中:

@interface ClassA()
  @property (nonatomic, strong, readwrite) NSString *displayString;
@end

类似于
string=objectB.objectA.displayString
正在违反。根据德米特定律进行设计,可使软件更具可维护性和适应性


你应该尽量不要和陌生人说话。这是在您的示例中:
self
objectB
对话,
objectB
objectA
对话,但是
self
不应该与
objectA
对话,因为它是陌生人。

我建议在
ClassB.h
中使用只读字符串属性

B.h类:

@interface ClassB: NSObject
  @property (nonatomic, strong, readonly) ClassA *classA;
@end
@property (nonatomic, readonly) NSString *classAString;
B.m类:

@interface ClassB()
  @property (nonatomic, strong, readwrite) ClassA *classA;
@end
- (NSString *) classAString
{
   return self.classA.displayString;
}
这充当您需要的特定字符串的“getter”方法,并避免其他人访问classA

编辑:

其他人建议在ClassB.h中添加classA作为只读属性。这仍然允许修改classA属性,它只会保证classA不会被重新分配给另一个classA实例。

听起来您想要的是“框架”,而不是“私有”
@property()
声明

为此,请创建如下文件:

ClassA_Private.h

包含您的
@property()
声明的

然后在
ClassA.m
(在
@实现之前)和希望使用该
@属性的任何子类中导入“ClassA\u Private.h”


这是创建类扩展时的次要设计考虑事项;添加了具有跨子类和/或在框架内完全可访问的
@property
声明的功能,而无需对外公开。虽然您无法为iOS目标应用程序创建框架,但同样的功能仍然适用。

我正在研究readonly属性在objective C中的具体工作方式。如果readonly也允许修改,那么我喜欢您为string创建方法的风格。但假设类A有7个类似于显示字符串的属性,我想访问所有这些属性,那么编写返回所有7个属性的方法将需要大量代码。另外,我不是在评判,只是想了解更多。:)Readonly意味着只有getter方法可见,而不是该属性的setter。但是,除非将所有属性设置为只读,否则ClassA属性的setter仍然存在。所以另一个类可以做classB.classA.classA属性=你不想要的东西;我试过了,你是真的。甚至readOnly也可以访问classA的其他属性并对其进行更改。在我的C类中,我尝试了classB.classA.someOtherProperty=@“Change it”,它确实接受并更改了属性值。如果要保护A类的属性,请将其设置为只读。我建议对
classA
属性设置
readonly
,因为我错过了@tech\u learning想要保护classA属性的内容。我编辑了答案alreadyWell,
strong
在ARC范围中是默认值,而在非ARC范围中是
assign
。当然,这都是关于可保留的类型(对象)。现在一切都好了吗?事实上要清楚,在ARC中,对象类型的默认语义是
strong
,而
assign
则是默认语义。@Petro Korienev-你的意思是类似于我在上面的答案中为ClassB.m修改的吗?如果我修改的是真的,那么它不允许禁止访问classA属性。我试过了,在classC中,通过classB实例向修改过的classA属性添加了一些代码,它确实修改了属性。