很多开发iOS好几年的老鸟,可能都不太分的清.h文件和.m文件里各种结构的用途和区别。最近仔细研究了一下,写一篇文章记下来。 
一般的,写一个Class的时候,经常是这种格式(以UIViewController为例):

.h文件:

@interface ClassName{
NSString* _value1;
} @property(nonatomic,assign)NSString* value1; -(void)func1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

.m文件:

@interface ClassName(){
}
@end @synthesize value1; @implementation ClassName -(void)func1{
} @end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

大体上就是这个格式。很多人,包括我,在创建和使用Class时,直接就使用这样的模板。这个模板里有一些有意思的小东西,值得探讨,比如: 
1. 为什么.h文件和.m文件里各有1个@interface?它们分别有什么用? 
2. .h中,value1为什么要定义2遍? 
3. @synthesize有什么用? 
还有一些其它的问题,今天先解决上面提到的这几个。

为什么.h文件和.m文件里各有1个@interface?它们分别有什么用?

.h里面的@interface,不消说,是典型的头文件,它是供其它Class调用的。它的@property和functions,都能够被其它Class“看到”。

而.m里面的@interface,在OC里叫作Class Extension,是.h文件中@interface的补充。但是.m文件里的@interface,对外是不开放的,只在.m文件里可见。

因此,我们将对外开放的方法、变量放到.h文件中,而将不想要对外开放的变量放到.m文件中(.m文件的方法可以不声明,直接用)。

有的同学看到Class Extension,可能会想到OC里的@protocol。是的,它们都是对一个Class的扩展。不过它们的区别也很明显:

Class Extension只能用在能得到源代码的情况下,而@protocol在得不到源码的时候也可以使用。

因此@protocol一般用作对一些系统Class的扩展,常见的比如对NSString、UIView等。

.h中,value1为什么要定义2遍?

当然,现在@interface{}里的定义也可以省略掉了,不过原理还是要搞清楚。

严格来说@interface{}里定义的变量,叫作instance variable,它是这个Class内部真正的全局变量。然而这个instance variable是不对外公开的,因此我们还需要一个对外公开的东西来调用,就是@property 
@property是对外的,它其实是告诉大家,我这个Class里,有一个变量的set/get方法。比如,@property NSString* string; 就是说,本Class里有一个getString/setString供你们调用。

因此需要2次声明。当然现在lldb也升级了,只要你声明了@property,它就可以自动创建对应的全局变量。

@synthesize有什么用?

@property 一个变量后,在@implementation里再@synthesize一下,相信是很多人的习惯。但是为什么要有这个@synthesize方法呢?

@property是对外声明了Class的get/set方法,然后我们就需要在.m文件里手写get/set方法。这可就麻烦了,1个变量对应2个方法,假如一个Class里有10个变量,那岂不是要写20个方法?烦也烦死唠。

@synthesize帮我们解决了这个问题。@synthesize在.m文件里自动生成了get/set方法。因此,我们只要在@implementation后面加上一行:@synthesize 就可以自动生成get/set方法了,省掉了很多麻烦。比如@synthesize value1 = _value1;的意思就是,将instance variable _value1用作getValue1和setValue1方法里。

get/set方法有时候是比较复杂的,因为它和变量的属性相关,就是@property(nonatomic, assign/retain(strong/weak))这就和内存有关了。然而@synthesize为我们做了这些事情,就不要再为这些事情烦恼了!

更方便的是,从Xcode4.4开始,编译器会自动为每一条@property都添加一条对应的@synthesize,因此以后我们只要写一个@property就可以了!

PS:这些在Swift貌似都不是个事儿了。话说到现在都没怎么接触过Swift,真是罪过罪过。

Objective-C中.h文件、.m文件中@interface、@synthesize及其它的更多相关文章

  1. iOS开发之解决CocoaPods中“.h”头文件找不到的问题,简单粗暴的方法

    如果是拖进工程中的framework或者第三方文件,如果找不到,删除了重新添加或者修改search path地址,如果不知道怎么修改,在工程文件夹中,找到对应的文件,然后将文件拖到修改文件地址的位置, ...

  2. Visual Studio 2010中的stdafx.h和targetver.h两个头文件是有什么用?

    来自百度~stdafx.h中没有函数库,只是定义了一些环境参数,使得编译出来的程序能在32位的操作系统环境下运行. Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程 ...

  3. C++中#include包含头文件带 .h 和不带 .h 的区别

    C++中#include包含头文件带 .h 和不带 .h 的区别? 如 #include <iostream> 和 #include <iostream.h> 包含的东西有哪些 ...

  4. C++中头文件(.h)和源文件(.cpp)都应该写些什么

    头文件(.h): 写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但一般来说不写出具体的实现. 在写头文件时需要注意,在开头和结尾处必须按照如下样式加上预编译语句(如下): ...

  5. Visual Studio 中使用万能头文件 #include <bits/stdc++.h>

    最近开始使用VS,之前用的DEV C++软件可直接使用 #include <bits/stdc++.h>  ,但VS中并没有,为了使用方便,可直接在VS中添加此头文件,方法如下: 1.在安 ...

  6. C++ 中头文件(.h)和源文件(.cc)的写法简述

    用C++编写比较大型的项目时,文件的分割管理确实确实是非常必要的 .下面就非常简洁明了地谈谈头文件(.h)和源文件(.cc)应该怎么写. 头文件(.h):写类的声明(包括类里面的成员和方法的声明).函 ...

  7. vc++中 .H 头文件引用的顺序与符号关系

    在使用 #include "math.h"  和 #include <math.h>时,引号 与尖括号的区别如下 此时math.h_1 在工程文件中 math.h_2 ...

  8. C 语言项目中.h文件和.c文件的关系

    http://blog.csdn.net/xingkong_678/article/details/38639847 关于两者以前的关系,要从N年以前说起了~ long long ago,once a ...

  9. xcode中的.h和.m文件分别是什么意思?各有什么用?

    .h 表示头文件,用来声明各种成员变量,方法,属性之类的.在import的时候用头文件. .m 主要用来实现.h 里声明的方法.举个例子,如果要写一个方法,你要在.h里先声明: - (void)myM ...

  10. [Swift]在Swift项目中创建桥接头文件,Swift文件和Objective-C文件相互调用

    创建一个Swift项目[demo],以下内容Swift文件和Objective-C文件相互调用都是在Swift项目中. 一.Swift文件调用Objective-C文件 新建文件夹[SupportFi ...

随机推荐

  1. linux下C++修改文件内容

    C fwrite在任意位置写入文件,并可修改文件内容 想实现类似迅雷那样下载时可以从文件半中间写入的功能 #include<stdio.h> int main() { FILE *fp; ...

  2. LINUX之内网渗透提权

    在渗透测试过程中,经常遇到如下情形,内部网络主机通过路由器或者安全设备做了访问控制,无法通过互联网直接访问本地开放的服务,Windows方 面,国内通常选择Lcx.exe来进行端口转发,在应用方面大多 ...

  3. time_t和SYSTEMTIME之间的相互转换 【转】

    time_t和SYSTEMTIME之间的相互转换 #include <ctime> /* **time_t转SYSTEMTIME */ SYSTEMTIME TimetToSystemTi ...

  4. 纯CSS实现文字一行居中,多行左对齐的方法

    其实这种需求还是蛮常见的,主要用于产品列表页面,用于产品图片下面,显示产品的名称. 想要实现的效果为: 未知文字长度,当文字长度小于盒子宽度,也就是一行时,文字居中. 当文字长度大于盒子的宽度,会自动 ...

  5. Strategy Pattern(策略模式)

    Head First定义: 策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式的设计原则主要有三个: 找出应用中可能需要变化的部分,把它们独 ...

  6. conkey conf

    update_interval 1.0 # 更新时间间隔double_buffer yes # 双缓存,解决Conky闪烁问题use_xft yes # 自定义字体xftfont DejaVu San ...

  7. block高级功能

    /* -*- c++ -*- */ /* * Copyright 2004,2007,2009,2010,2013 Free Software Foundation, Inc. * * This fi ...

  8. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)如何在TwinCAT Scope中做变量监控

    为了更好的监控变量,可以打开ScopeView即变量监控器   添加一个Scope View,然后右击添加一个Channel   我们在之前登录的时候可以选择Run-Time的端口(默认是801)   ...

  9. .Net Framework 之 托管代码和非托管代码的区别

    一.什么是托管代码(managed code)? 托管代码:是微软的中间语言(IL),即微软中间语言MSIL(Microsoft Interspace Language). “ 源代码→机器码 ”运行 ...

  10. 约瑟夫环 java实现

    问题: N个人从1到N编号.围城一圈,从1開始报数, 数到X时,将X的编号输出,并将那个人踢出, 下一个从1再開始报数,直到全部人都出去 思路: 就是计数.移除,没有太深的思想,直接上代码: pack ...