【问题标题】:Class Extension for Core Data Methods核心数据方法的类扩展
【发布时间】:2012-04-02 23:54:10
【问题描述】:

有人可以告诉我如何“隐藏”标准核心数据设置器吗?

我知道在 Objective-C 中没有真正定义“私有”方法的方法,但请阅读有关使用扩展来实现类似结果的信息。问题是,我想将其应用于核心数据类。我想隐藏为某些属性创建的标准设置器,并且只从其他公开的设置器中调用它们。

一个例子:我的核心数据对象有一个 BOOL 'collected' 和一个日期 'dateCollected'。我已经想出了如何将 setDateCollected 添加到 setCollected,但现在我想“隐藏”收集的集合,这样就不能那么容易地直接调用它(当我可能忘记手动设置 dateCollected 时)。

澄清一下,让我绊倒的部分是“@dynamic”调用——我不知道它们应该放在哪里。

编辑 - 我想我错过了一部分。我可以将@property 声明移动到实现文件中就好了。但我希望 setter 被隐藏,而 getter 保持公开。我想我需要替换@property,但我不知道如何为核心数据对象执行此操作。

【问题讨论】:

  • @implementation? - 他们通常居住的地方。
  • 如果我将它放在@implementation 中,它根本不会隐藏。

标签: objective-c ios core-data


【解决方案1】:

您尝试做的事情不太可能带来好的结果。 Core Data 类非常精细地设置了图形层次结构,并且属性实现存在于超类中。也许您应该消除收集的变量,然后对 dateCollected 进行 nil 检查。另一种稍微复杂的方法是将其从数据模型中删除并使其成为常规 ivar。

编辑:好的,我查看了您评论中的信息。如果您遵守某些准则,它确实建议您可以覆盖实施。但是,下面的答案可能更好。将属性移动到私有接口。然后在返回私有属性值的公共接口(只读)中声明另一个属性;)。

【讨论】:

  • dateCollected 是一个简化的示例(虽然是个好主意)。此外,我认为重新定义 setter 是非常标准的做法,只要我使用 willChangeValueForKey 和 didChangeValueForKey。或者,也许您的意思是不建议“隐藏”方面?我不明白为什么会这样,因为标准制定者仍然存在,我只是没有将它们暴露给编译器。
  • 我不知道它是否是标准的,但我在我的项目中使用了 9 个或 10 个 Core Data 类。覆盖核心数据的可怕部分是我不知道 NSManagedObject 到底在做什么,而做错了就是通往 EXC_BAD_ACCESS 领域的快速门票。或者您是否在某个地方找到了这些信息?也许比我聪明的人有更好的答案,但在那之前^^;
  • 啊,这很有趣,但是我认为下面的人在更安全的轨道上,所以我更新了我的答案。但是,既然是根据他的回答...我不会把功劳~^^
  • 谢谢 - 真的就这么简单 :)
【解决方案2】:

您在实现文件中定义私有方法。如果头文件中未显示方法,则根据定义,它是私​​有的。澄清一下,以下是定义公共属性和方法的方式。

@interface MyAppViewController : UIViewController

@property (strong, nonatomic) NSString *myPublicStringObject;

- (NSString *) myPublicMethodTakingInputString:(NSString *) input;

@end

在实现文件中,可以如下定义私有属性和方法。

#import "MyAppViewController.h"

// Declare private properties and methods inside the following interface extension
@interface MyAppViewController ()

@property (strong, nonatomic) NSNumber     *myPrivateNumber;
@property (strong, nonatomic) NSString     *myPrivateStringObject;

- (void) myPrivateMethod1;
- (NSString *) myPrivateMethod2WithIntegerInput:(NSInteger) input;

@end


@implementation MyAppViewController

@synthesize myPublicStringObject;
@synthesize myPrivateNumber;
@synthesize myPrivateStringObject;

// Implement all methods declared in header and private interfaces here in no particular order
- (NSString *) myPublicMethodTakingInputString:(NSString *) input
{
// code for myPublicMethodTakingInputString
}

- (void) myPrivateMethod1
{
}

- (NSString *) myPrivateMethod2WithIntegerInput:(NSInteger) input
{
}


// Implement any other private method not declared
- (NSString *) myUndeclaredPrivateMethod1:(NSString *) input
{
// code for myUndeclaredPrivateMethod1
}


- (id) myUndeclaredPrivateMethod2
{
// code for myUndeclaredPrivateMethod2
}

...等等。

这个描述当然是针对 iOS 5 的。 iOS3 和 4 的语法类似,只是私有即时变量 (iVars) 出现在头文件中——这对新手来说可能非常混乱。 iOS 5 清理了这一点,不需要即时变量出现在任何地方。

【讨论】:

  • 这很接近 - 我想我错过了重要的部分(更新了 Q,我很抱歉) - 我需要保持 getter 公开,所以我想我必须替换 @property,但不确定如果核心数据实体有特殊行为。
  • 您可以为核心数据对象实现一个类别。在文档中查找类别。它们看起来像私有接口,只是类别在大括号内具有类别名称。例如,创建上面示例对象的类别可能类似于 \@interface MyAppViewController (Create) //"my code" \@end。在“我的代码”中将是我创建对象时调用的所有方法。
  • 一般来说,您可以通过覆盖@property 的setter 部分来保持setter 私有。例如。对于我的对象“\@property (strong) NSString myObject;”我可以用“- (void) setMyObject:(NSString *) string { //setter code }”覆盖 setter 现在,每次有人想要分配给属性时都会调用它。瞧!
猜你喜欢
  • 2013-08-14
  • 2012-05-12
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2015-12-03
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多