English 中文(简体)
在实现中创建方法而不在标头中定义
原标题:
  • 时间:2008-12-28 01:23:26
  •  标签:

我如何在类的@实现中创建一个方法,而不在@接口中定义它?

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

这是可能的吗?

这是我的例子。我有一个小程序,从文件中读取待办任务清单。

这是 @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

这是实现部分的一部分:

-(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;
最佳回答

如果您在任何调用方法的代码之前放置该方法的实现,则无需在头文件中定义它。

因此,在这种情况下,将 loadListWithName:放在 initListOfName: 之前的@ implementation块中,就可以了。

注意:仅仅因为在头文件中没有定义并不意味着这个方法不能被对象外的代码调用。Objective-C没有私有方法。

问题回答

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

I am sorry, but ".h" is not a complete sentence or phrase that can be translated into Chinese. It is commonly used as a file extension in programming languages. Can you provide more context or information about what you want to translate?

@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

你可以使用类别

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

@implementation TDTaskList(TDTaskListPrivate)

// implementation of initListOfName and loadListWithName ...

@end

你有两个合理的选择。两种选择已经基本描述过了,但在我的观点中有一点不太清楚,甚至是完全错误的。

类别不属于它们之一,因为据我所知,它们的目的完全是将实现分为多个源文件。

  • Do as Nathan described above. Though he is wrong with his last assumption (private methods).
  • Use a private method extension definition to allow forward referencing as follows:
    1. remove the definition of loadListWithName from your header entirely
    2. add the following into the source (.m) before the @implementation block
    @interface TDTaskList (PrivateMethods)
    -(NSArray*)loadListWithName:(NSString*)aName;
    @end
    
    @implementation ...
    





  • 相关问题