.h和.m文件中@interface定义的区别

86

通常我们使用

@interface interface_name : parent_class <delegates>
{
......
}
@end 

在.h文件中声明方法,在.m文件中我们合成了在.h文件中声明的变量的属性。

但是在一些代码中,这个@interface.....@end方法也会保留在.m文件中。这是什么意思?它们之间有什么区别?

同时,对于在.m文件中定义的接口文件的getter和setter,请简述一些相关内容...

3个回答

65

通常会额外添加一个@interface来定义包含私有方法的类别(category):

Person.h:

@interface Person
{
    NSString *_name;
}

@property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)person;
@end

Person.m:

:人员文件(Person.m):
@interface Person () //Not specifying a name for the category makes compiler checks that these methods are implemented.

-(void)startThinkOfWhatToHaveForDinner;
@end


@implementation Person

@synthesize name = _name;

-(NSString*)makeSmallTalkWith:(Person*)person
{
    [self startThinkOfWhatToHaveForDinner];
    return @"How's your day?";
}


-(void)startThinkOfWhatToHaveForDinner
{

}

@end

“私有类别”(一个没有名称的类别的正确名称不是“私有类别”,而是“类扩展”).m 防止编译器发出方法已定义的警告。但是,因为 .m 文件中的 @interface 是一个类别,所以你不能在其中定义实例变量。

更新于2012年8月6日:自本答案撰写以来,Objective-C 已经发生了变化:

  • 实例变量可以在类扩展中声明(一直都可以 - 答案是错误的)
  • @synthesize 不再需要
  • 现在可以在 @implementation 的顶部用花括号声明实例变量:

也就是说,

@implementation { 
     id _ivarInImplmentation;
}
//methods
@end

4
小侧记:在声明私有接口时,不要实际在括号中放置任何内容。否则,它将创建一个分类,而您不希望这样。@interface Person()就足够了。 - Itai Ferber
4
如果有人想了解更多关于类别的内容,这个页面对我非常有用。 - Tim
1
如果括号中没有任何内容,则实际上称为“类扩展”,而不是“类别”。 - Paul.s
由于某种原因,我能够在.m文件中的@interface Person()@end之间不声明私有方法就创建它。例如,我可以只写-(void)startThinkOfWhatToHaveForDinner{}在实现中并且不会出问题。这是iOS6的新特性吗?还是我漏掉了什么? - giant91
6
这个答案相当古老,自从它最初写出来以来,编译器已经大幅改进。如果方法体是“可见”的,编译器现在不再需要方法的声明。这意味着类扩展(@interface className ())通常只包含私有的@property - Benedict Cohen
显示剩余2条评论

11

The concept is that you can make your project much cleaner if you limit the .h to the public interfaces of your class, and then put private implementation details in this class extension.

when you declare variable methods or properties in ABC.h file , It means these variables properties and methods can be access outside the class

@interface Jain:NSObject
{
    NSString *_name;
}

@property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)jain;
@end

@Interface allows you to declare private ivars, properties and methods. So anything you declare here cannot be accessed from outside this class. In general, you want to declare all ivars, properties and methods by default as private

Simply say when you declare variable methods or properties in ABC.m file , It means these variables properties and methods can not be access outside the class

@interface Jain()
    {
        NSString *_name;
    }

    @property(readwrite, copy) NSString *name;
    -(NSString*)makeSmallTalkWith:(Person*)jain;
    @end

0

你甚至可以在.m文件中创建其他类,例如继承自.h文件中声明的类但具有一些略微不同行为的其他小类。你可以在工厂模式中使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接