在实现中创建方法而不在头文件中定义

时间:2008-12-28 01:23:26

标签: objective-c encapsulation

如何在类的@implementation中创建方法而不在@interface中定义它?

例如,我有一个构造函数,它进行一些初始化,然后从文件中读取数据。我想将文件读取代码分解为一个单独的方法,然后我在构造函数中调用它。我不想在标题中定义此方法,因为它仅对此@implementation上下文是私有的。

这可能吗?

这是我的例子。我有一个小程序,它从文件中读取了Todo任务列表。

这是@interface:

@interface TDTaskList : NSObject {
  NSString* name; // The name of this list.
  NSMutableArray* tasks;  // The set of tasks in this list.
}

-(id)initListOfName:(NSString*)aName;
-(NSArray*)loadListWithName:(NSString*)aName;

@end

这是@implementation的一部分:

-(id)initListOfName:(NSString*)aName {
  if (self = [super init]) {
    name = aName;

    NSArray* aTasks = [self loadListWithName:aName];
    tasks = [NSMutableArray arrayWithArray:aTasks];
  }

  return self;
}

-(NSArray*)loadListWithName:(NSString*)aName {
  // TODO This is a STUB till i figure out how to read/write from a file ...

  TDTask* task1 = [[TDTask alloc] initWithLabel:@"Get the Milk."];
  TDTask* task2 = [[TDTask alloc] initWithLabel:@"Do some homework."];

  return [NSArray arrayWithObjects:task1, task2, nil];
}

我想要做的是必须在界面中定义以下内容:

-(NSArray*)loadListWithName:(NSString*)aName;

4 个答案:

答案 0 :(得分:10)

如果在任何调用它的代码之前放置方法的实现,则不需要在标题中定义它。

所以在这种情况下,将 loadListWithName:放在@implementation块中的 initListOfName:前面,这样会很好。

注意:仅仅因为它未在标题中定义并不意味着该方法不能被对象外部的代码调用。 Objective-C没有私有方法。

答案 1 :(得分:6)

正如安迪在评论中暗示的那样,你可以使用Extensions(看起来像没有名字的类别)。不同之处在于必须实现扩展中声明的方法,而编译器不验证您是否实现了在类别中声明的方法。

·H:

@interface MyObject : NSObject
{
    NSNumber *number;
}
- (NSNumber *)number;
@end

的.m:

@interface MyObject ()
- (void)setNumber:(NSNumber *)newNumber;
@end

@implementation MyObject

- (NSNumber *)number
{
    return number;
}
- (void)setNumber:(NSNumber *)newNumber
{
    number = newNumber;
}
@end

答案 2 :(得分:2)

您可以使用categories

// In TDTaskList.m
@interface TDTaskList(TDTaskListPrivate)
-(id)initListOfName:(NSString*)aName;
-(NSArray*)loadListWithName:(NSString*)aName;
@end

@implementation TDTaskList(TDTaskListPrivate)

// implementation of initListOfName and loadListWithName ...

@end

答案 3 :(得分:1)

您有两个合理的选择。两者基本上已经描述过,但恕我直言有点不清楚甚至是错误的。

类别不是其中之一,因为它们是AFAIK意味着将实现分解为多个源文件的完全不同的目的。

  • 按照上面描述的那样做。虽然他最后的假设是错误的(私人方法)。
  • 使用私有方法扩展定义允许转发引用,如下所示:

    1. 完全从标题中删除loadListWithName的定义
    2. 在@implementation块
    3. 之前将以下内容添加到源(.m)中
      @interface TDTaskList (PrivateMethods)
      -(NSArray*)loadListWithName:(NSString*)aName;
      @end
      
      @implementation ...