代码之家  ›  专栏  ›  技术社区  ›  tech_human

目标C中的私有v/s公共类财产

  •  1
  • tech_human  · 技术社区  · 11 年前

    试图在目标C的基础上强化我的OOP基础。如果我的解释太长,很抱歉。 我的应用程序中有三个类,分别是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
    
    4 回复  |  直到 11 年前
        1
  •  3
  •   Petro Korienev Alexey Lobanov    11 年前

    在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 是默认的修改器-你可以去掉它们。然而,它们提高了代码的可读性。
    编辑:如果你想禁止访问A级财产,请使用相同的技巧。上面建议的代码将只禁止修改classB的classA属性。对于ClassA的displayString:
    在A级中:

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

    在A级中:

    @interface ClassA()
      @property (nonatomic, strong, readwrite) NSString *displayString;
    @end
    
        2
  •  1
  •   paulrehkugler    11 年前

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

    等级B.h:

    @property (nonatomic, readonly) NSString *classAString;
    

    等级B.m:

    - (NSString *) classAString
    {
       return self.classA.displayString;
    }
    

    这可以作为您需要的特定字符串的“getter”方法,并避免其他人访问classA。

    编辑:

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

        3
  •  1
  •   bbum    11 年前

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

    要执行此操作,请创建如下文件:

    ClassA_Private.h类

    包含您的 @属性() 公告

    然后 #import "ClassA_Private.h" 在你的 ClassA.m (在 @implementation )并且在任何想要使用它的子类中 @property .

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

        4
  •  0
  •   Community CDub    5 年前

    有点像 string = objectB.objectA.displayString; 正在违反 Law of Demeter .根据德米特定律进行设计会产生更具可维护性和适应性的软件。

    你应该一直努力 不要和陌生人说话 。在你的例子中: self 与交谈 objectB 对象B 与交谈 objectA 但是 自己 不应该和 对象A 因为这是一个陌生人。