Objective-C 中 .m 文件中的 @interface

前言:博主為一枚因?yàn)楣ぷ餍枰谄D難地新學(xué) IOS 開發(fā)的程序媛淡喜,對(duì)于 Objective-C 還不甚了解陨帆,所以博文內(nèi)容可能不是那么嚴(yán)謹(jǐn),如有童鞋發(fā)現(xiàn)不妥之處已亥,還望告知博主熊赖,萬分感謝!

問題描述

博主今早在看一份 Objective-C 的代碼時(shí)虑椎,在 SignInViewController.m 文件中看到如下代碼片段:

#import "SignInViewController.h"

@interface SignInViewController ()
@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *userPassTextField;
@property (weak, nonatomic) IBOutlet UIButton *signInBtn;
@property (strong, nonatomic) NSString *userName;
@property (strong, nonatomic) NSString *userPass;
@end

然后博主在仿照寫代碼時(shí)震鹉,一不留神將 @interface SignInViewController () 寫成了 @interface SignInViewController : NSOject,然后 XCode 給出了錯(cuò)誤提示捆姜,后面回查才發(fā)現(xiàn)自己把代碼寫錯(cuò)了传趾,并且還并不了解 .m 文件中的這個(gè) @interface SignInViewController () 是什么意思,所以就查了一波資料娇未。

問題解析

查閱資料后發(fā)現(xiàn)墨缘,該處涉及到 Objective-C 中分類和擴(kuò)展的知識(shí)點(diǎn)星虹。

知識(shí)點(diǎn)分析

分類 Category

官方解釋:

A category allows you to add methods to an existing class
—even to one for which you do not have the source. 
Categories are a powerful feature that allows you to 
extend the functionality of existing classes without subclassing. 
Using categories, you can also distribute the implementation 
of your own classes among several files. 

Adding Methods to Classes

You can add methods to a class by declaring them in an interface file
under a category name and defining them in an implementation file 
under the same name. 
The category name indicates that the methods are additions to a class declared elsewhere, 
not a new class. 
You cannot, however, use a category to add additional instance variables to a class.

The methods the category adds become part of the class type. 

Category methods can do anything that methods defined in the class proper can do. 
At runtime, there’s no difference. 
The methods the category adds to the class are inherited by all the class’s subclasses, 
just like other methods.

The declaration of a category interface looks very much like a class interface declaration—
except the category name is listed within parentheses after the class name 
and the superclass isn’t mentioned. 
Unless its methods don’t access any instance variables of the class,
 the category must import the interface file for the class it extends:

#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end

Note that a category can’t declare additional instance variables for the class;
it includes only methods. 
However, all instance variables within the scope of the class 
are also within the scope of the category. 
That includes all instance variables declared by the class, 
even ones declared @private.

There’s no limit to the number of categories that you can add to a class, 
but each category name must be different, 
and each should declare and define a different set of methods.

分類允許開發(fā)者為一個(gè)已有的類添加新功能零抬,即便開發(fā)者沒有該類的源碼也可以如此使用镊讼。分類給予了開發(fā)者一個(gè)擴(kuò)展已有類功能,而無需繼承該類的強(qiáng)大特性平夜,提供了不同于繼承的便利蝶棋。通過分類為類添加的方法就自然而然成為該類的一部分,類似于該類原來已有的方法忽妒,所有繼承自該類的子類均自動(dòng)擁有這些方法玩裙。

注意:

  1. 可以通過分類為已有類添加新功能,而不能通過分類添加新的實(shí)例變量段直;
  2. 除非在分類中實(shí)現(xiàn)的方法均無需訪問該類中的實(shí)例變量吃溅,否則在分類中必須導(dǎo)入類的 interface 文件;
  3. 導(dǎo)入了類的 interface 文件后鸯檬,該類中定義的所有實(shí)例變量均自動(dòng)被分類所擁有决侈,即便是 @private 定義的實(shí)例變量,分類也可以訪問喧务;
  4. 可以為一個(gè)類添加任意數(shù)量的分類赖歌,只需要保證每個(gè)分類名稱及定義在分類中的方法不同即可。

分類的使用:

使用步驟:
第一步:創(chuàng)建一個(gè)在指定分類名下帶有接口的新文件功茴,在該文件中添加想要添加的新功能庐冯;
第二步:在同名 implementation 文件中實(shí)現(xiàn)這些功能

#import <Foundation/Foundation.h>  
  
/** NSString 表示將要添加分類的類名稱,該類必須是已存在的坎穿。  
  * Test 為分類名稱  
  * testString 為新添加的方法
  */  

@interface NSString (Test)  
-(NSString*) testString;  
@end  
  
@implementation NSString (Test)    
-(NSString*) testString  
{  
    // 方法實(shí)現(xiàn)
    NSString str = @"test string";
    return str;  
}  
@end  

擴(kuò)展 Extension

官方解釋:

Class extensions are like anonymous categories,
except that the methods they declare must be implemented
in the main @implementation block for the corresponding class. 
Using the Clang/LLVM 2.0 compiler, you can also declare properties 
and instance variables in a class extension.

A common use for class extensions is to redeclare property that 
is publicly declared as read-only privately as readwrite:

@interface MyClass : NSObject
@property (retain, readonly) float value;
@end
 
// Private extension, typically hidden in the main implementation file.
@interface MyClass ()
@property (retain, readwrite) float value;
@end
Notice that (in contrast to a category) no name is given in the parentheses
in the second @interface block.

It is also generally common for a class to have a publicly declared API and 
to then have additional methods declared privately for use solely by the class 
or the framework within which the class resides. Class extensions allow you 
to declare additional required methods for a class in locations other than 
within the primary class @interface block.

大意為:擴(kuò)展和匿名分類很像展父,不過和匿名分類還是有很大的區(qū)別,擴(kuò)展中可以添加實(shí)例變量玲昧,擴(kuò)展中定義的方法必須在相應(yīng)類的 @implementation 代碼塊中實(shí)現(xiàn)犯祠。從 Xcode 4 之后就推薦在自定義類的 .m 文件中使用擴(kuò)展,這樣就能保證良好的代碼封裝性酌呆,避免把私有接口暴露給外面衡载。

擴(kuò)展的慣用法:

  1. 重新將一個(gè)在外部 interface 中聲明為 readonly 的變量聲明為 readwrite 類型,既便于在當(dāng)前類中讀寫該變量隙袁,又能夠避免外部修改痰娱;
  2. 在外部 interface 中聲明公有 API,而在擴(kuò)展中聲明私有方法菩收,可以避免將私有接口暴露于外部梨睁。

擴(kuò)展的使用步驟:
第一步:創(chuàng)建 MyClass.h 文件,在 @interface MyClass 中聲明可供外部調(diào)用的公有 API娜饵;
第二步:創(chuàng)建 MyClass.m 文件坡贺,在 @interface MyClass(){} 擴(kuò)展中聲明所需的實(shí)例變量和方法;
第三步:在 @implementation 代碼塊中實(shí)現(xiàn)在 MyClass.h 文件和 @interface MyClass(){} 擴(kuò)展中聲明的方法。

// 如下代碼位于 MyClass.h 文件中
@interface MyClass : NSObject
- (float)value;
@end
 
// 如下代碼位于 MyClass.m 文件中
@interface MyClass () {  // 擴(kuò)展
    float value;
}
- (void)setValue:(float)newValue;
@end
 
// 實(shí)現(xiàn)
@implementation MyClass
- (float)value {
    return value;
}
- (void)setValue:(float)newValue {
    value = newValue;
}
@end

分類與擴(kuò)展的區(qū)別

  1. 分類只能為已有類添加新功能遍坟,不能在分類中添加新的實(shí)例變量拳亿;而擴(kuò)展不僅可以添加新功能,還能添加實(shí)例變量肺魁;
  2. 通過分類為已有類添加新功能時(shí)隔节,需要在類名后面的小括號(hào)中指定分類名,同時(shí)可以通過指定多個(gè)分類名為已有類添加這多個(gè)分類中的功能瘾晃;而使用擴(kuò)展時(shí)幻妓,類名后的小括號(hào)中不添加任何東西涌哲;
  3. 擴(kuò)展中聲明的方法必須在相應(yīng)類的 @implementation 代碼塊中實(shí)現(xiàn),而分類則沒有此要求哪廓,也就是說分類與類之間是獨(dú)立的,不與特定的類相關(guān)涡真,而擴(kuò)展是與特定的類相關(guān)的哆料,所以在擴(kuò)展中聲明的代碼必須在相關(guān)類的 @implementation 主代碼塊中實(shí)現(xiàn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末东亦,一起剝皮案震驚了整個(gè)濱河市唬渗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壮啊,老刑警劉巖歹啼,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異藤树,居然都是意外死亡份企,警方通過查閱死者的電腦和手機(jī)司志,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門骂远,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腰根,“玉大人额嘿,你說我怎么就攤上這事《В” “怎么了球拦?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵坎炼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我檩淋,道長(zhǎng)狼钮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮福稳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鼓拧。我一直安慰自己,他們只是感情好钮糖,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布店归。 她就那樣靜靜地躺著酪我,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秩伞。 梳的紋絲不亂的頭發(fā)上欺矫,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天穆趴,我揣著相機(jī)與錄音,去河邊找鬼阅羹。 笑死教寂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的导梆。 我是一名探鬼主播看尼,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼藏斩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼却盘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兆览,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤抬探,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后线梗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缠导,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年孩饼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竹挡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梯码,死狀恐怖轩娶,靈堂內(nèi)的尸體忽然破棺而出框往,到底是詐尸還是另有隱情,我是刑警寧澤许溅,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布贤重,位于F島的核電站游桩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盹憎。R本人自食惡果不足惜陪每,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一檩禾、第九天 我趴在偏房一處隱蔽的房頂上張望疤祭。 院中可真熱鬧,春花似錦戏售、人聲如沸灌灾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涯冠。三九已至,卻和暖如春盆佣,著一層夾襖步出監(jiān)牢的瞬間共耍,已是汗流浹背吨瞎。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工痹兜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颤诀。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓字旭,卻偏偏與公主長(zhǎng)得像对湃,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子遗淳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容