4

如何在类的@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

4 回答 4

10

If you place the implementation of a method before any code that calls it you do not need to define it in the header.

So in this case put loadListWithName: in front of initListOfName: in the @implementation block and it will be good.

Note: Just because it is not defined in the header does not mean the method cannot be called by code outside of the object. Objective-C does not have private methods.

于 2008-12-30T00:23:11.327 回答
6

As Andy hinted in the comments, you can use Extensions (which look like a category without a name). The difference is that you must implement the methods declared in an extension whereas the compiler doesn't verify that you implement methods declared in a category.

.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
于 2008-12-28T10:25:00.397 回答
2

您可以使用类别

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

@implementation TDTaskList(TDTaskListPrivate)

// implementation of initListOfName and loadListWithName ...

@end
于 2008-12-28T01:30:12.303 回答
1

You have two reasonable options. Both were basically described already but IMHO were a bit unclear or even plain wrong.

Categories are not one of them as they are AFAIK meant for the entirely different purpose of breaking implementations into multiple source files.

  • 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 ...
    

  • 于 2009-04-30T18:31:03.180 回答