ios NSObject.h 詳解

原文地址:http://blog.csdn.net/zeng_zhiming/article/details/70225456

加載及初始化類

運(yùn)行時加載類或分類調(diào)用該方法,每個類只會調(diào)用一次

+(void)load;

類實例化使用前需要先初始化,一個類調(diào)用一次,如果子類沒有實現(xiàn)該方法則會調(diào)用父類方法

+(void)initialize;

loadinitialize區(qū)別在于:load是只要類所在文件被引用就會被調(diào)用,而initialize是在類或者其子類的第一個方法被調(diào)用前調(diào)用。所以如果類沒有被引用進(jìn)項目,就不會有load調(diào)用立砸;但即使類文件被引用進(jìn)來,但是沒有使用初茶,那么initialize也不會被調(diào)用颗祝;load每個類只會調(diào)用一次,initialize也只調(diào)用一次恼布,但是如果子類沒有實現(xiàn)initialize方法則會調(diào)用父類的方法螺戳,因此作為父類的initialize方法可能會調(diào)用多次。

2折汞、分配內(nèi)存空間及初始化對象

ZMStudent *student = [ZMStudent new];  

ZMStudent *student2 = [[ZMStudent alloc] init];  

ZMStudent *student3 = [[ZMStudent allocWithZone:nil] init];  

創(chuàng)建新對象時倔幼,首先調(diào)用alloc為對象分配內(nèi)存空間,再調(diào)用init初始化對象字支,如[[NSObject alloc] init]凤藏;而new方法先給新對象分配空間然后初始化對象,因此[NSObject new]等同于[[NSObject alloc] init]堕伪;關(guān)于allocWithZone方法,官方文檔解釋該方法的參數(shù)是被忽略的栗菜,正確的做法是傳nil或者NULL參數(shù)給它欠雌。

3、給對象發(fā)送消息(執(zhí)行方法)

(1)直接調(diào)用

    // 調(diào)用無參無返回值方法  
    [student running];  
    // 調(diào)用有參無返回值方法  
    [student readingWithText:@"Hello World!"];  
    // 調(diào)用有參有返回值方法  
    NSNumber *sum = [student sumWithNum:@(2) num2:@(3)];  

我們通常都采用這種直接調(diào)用的方式疙筹,給對象發(fā)消息執(zhí)行方法富俄。這種方式調(diào)用編譯時會自動校驗方法、參數(shù)而咆、返回值是否正確霍比。因此我們必須在頭文件中聲明方法的使用。

(2)使用performSelector執(zhí)行

- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

    // 先判斷對象是否能調(diào)用方法暴备,再執(zhí)行調(diào)用方法  
    if ([student respondsToSelector:@selector(running)]) {  
    // 調(diào)用無參無返回值方法  
    [student performSelector:@selector(running)];  
    }  
    if ([student respondsToSelector:@selector(readingWithText:)]) {  
    // 調(diào)用有參無返回值方法  
    [student performSelector:@selector(readingWithText:) withObject:@"Hello World"];  
    }  
    if ([student respondsToSelector:@selector(sumWithNum:num2:)]) {  
    // 調(diào)用有參有返回值方法  
    NSNumber *sum = [student performSelector:@selector(sumWithNum:num2:) withObject:@(2) withObject:@(8)];  
    }  

使用performSelector:是運(yùn)行時系統(tǒng)負(fù)責(zé)去找方法悠瞬,在編譯時候不做任何校驗;因此在使用時必須先使用respondsToSelector:檢查對象是否能調(diào)用方法涯捻,否則可能出現(xiàn)運(yùn)行崩潰浅妆。performSelector:常用于調(diào)用運(yùn)行時添加的方法,即編譯時不存在障癌,但是運(yùn)行時候存在的方法凌外。另外需要注意的是performSelector:系統(tǒng)提供最多接受兩個參數(shù)的方法,而且參數(shù)和返回都是id類型涛浙,并不支持基礎(chǔ)數(shù)據(jù)類型(如:int, float等)康辑。

(3)使用IMP指針調(diào)用

    // 創(chuàng)建SEL  
    SEL runSel = @selector(running);  
    SEL readSel = NSSelectorFromString(@"readingWithText:");  
    SEL sumSel = NSSelectorFromString(@"sumWithNum:num2:");  
      
    // 調(diào)用無參無返回值方法  
    IMP rumImp = [student methodForSelector:runSel];  
    void (*runFunc)(id, SEL) = (voidvoid *)rumImp;  
    runFunc(student, runSel);  
      
    // 調(diào)用有參無返回值方法  
    IMP readImp = [[student class] instanceMethodForSelector:readSel];  
    void (*speakFunc)(id, SEL, NSString *) = (voidvoid *)readImp;  
    speakFunc(student, readSel, @"Hello World");  
      
    // 調(diào)用有參有返回值方法  
    IMP sumImp = [student methodForSelector:sumSel];  
    NSNumber *(*sumFunc)(id, SEL, NSNumber *, NSNumber *) = (voidvoid *)sumImp;  
    NSNumber *sum3 = sumFunc(student, sumSel, @(6), @(6));  

SEL 是方法的索引摄欲。IMP是函數(shù)指針,指向方法的地址疮薇。SELIMP是一一對應(yīng)的關(guān)系胸墙,因此我們可以通過修改對應(yīng)關(guān)系達(dá)到運(yùn)行時方法交換的目的。
創(chuàng)建SEL對象兩種方法:
1惦辛、使用@selector()創(chuàng)建
2劳秋、使用NSSelectorFromString()創(chuàng)建
獲取方法IMP指針兩種方法:
1、- (IMP)methodForSelector:(SEL)aSelector; 實例方法
2胖齐、+ (IMP)instanceMethodForSelector:(SEL)aSelector; 類方法

4玻淑、復(fù)制對象

// 兩個源數(shù)組  
NSArray *sourceArrayI = [NSArray arrayWithObjects:@"I", @"I", nil nil];  
NSMutableArray *sourceArrayM = [NSMutableArray arrayWithObjects:@"M", @"M", nil nil];  
  
// 兩個copy  
NSArray *copyArrayI = [sourceArrayI copy];  
NSArray *copyArrayM = [sourceArrayM copy];  
  
// 兩個mutableCopy  
NSMutableArray *mutableArrayI = [sourceArrayI mutableCopy];  
NSMutableArray *mutableArrayM = [sourceArrayM mutableCopy];

copy拷貝為不可變對象,mutableCopy拷貝為可變變量呀伙,copymutableCopy都可理解為復(fù)制了一個新對象补履。雖然copy對靜態(tài)對象只是引用計數(shù)加1,但是并不影響我們對復(fù)制前后的對象進(jìn)行使用剿另。需要注意的是對于容器對象而言箫锤,這兩個方法只是復(fù)制了容器本身,對容器中包含的對象只是簡單的指針引用雨女,并沒有深層復(fù)制谚攒。

5、獲取Class

    // 獲取類  
    Class curClass1 = [student class];  
    Class curClass2 = [ZMStudent class];  
      
    // 獲取父類  
    Class supClass1 = [student superclass];  
    Class supClass2 = [ZMStudent superclass];  

6氛堕、判斷方法

    // 初始化對象  
    ZMPerson *person = [ZMPerson new];  
    ZMStudent *student = [ZMStudent new];  
    ZMStudent *student2 = student;  
      
    // 判斷對象是否繼承NSObject  
    if ([student isProxy]) {  
    NSLog(@"student對象是繼承NSObject類");  
    }  
      
    // 判斷兩個對象是否相等  
    if ([student isEqual:student2]) {  
    NSLog(@"student對象與student2對象相等");  
    }  
      
    // 判斷對象是否是指定類  
    if ([person isKindOfClass:[ZMPerson class]]) {  
    NSLog(@"person對象是ZMPerson類");  
    }  
      
    // 判斷對象是否是指定類或子類  
    if ([student isKindOfClass:[ZMPerson class]]) {  
    NSLog(@"student對象是ZMPerson類的子類");  
    }  
      
    // 判斷是否是另一個類的子類  
    if ([ZMStudent isSubclassOfClass:[ZMPerson class]]) {  
    NSLog(@"ZMStudent類是ZMPerson類的子類");  
    }  
      
    // 判判斷對象是否遵從協(xié)議  
    if ([student conformsToProtocol:@protocol(NSObject)]) {  
    NSLog(@"student對象遵循NSObject協(xié)議");  
    }  
      
    // 判斷類是否遵從給定的協(xié)議  
    if ([ZMStudent conformsToProtocol:@protocol(NSObject)]) {  
    NSLog(@"ZMStudent類遵循NSObject協(xié)議");  
    }  
      
    // 判斷對象是否能夠調(diào)用給定的方法  
    if ([student respondsToSelector:@selector(running)]) {  
    NSLog(@"student對象可以調(diào)用‘running’方法");  
    }  
      
    // 判斷實例是否能夠調(diào)用給定的方法  
    if ([ZMStudent instancesRespondToSelector:@selector(running)]) {  
    NSLog(@"ZMStudent類可以調(diào)用‘running’方法");  
    }  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末馏臭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讼稚,更是在濱河造成了極大的恐慌括儒,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锐想,死亡現(xiàn)場離奇詭異帮寻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赠摇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門固逗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蝉稳,你說我怎么就攤上這事抒蚜。” “怎么了耘戚?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵嗡髓,是天一觀的道長。 經(jīng)常有香客問我收津,道長饿这,這世上最難降的妖魔是什么浊伙? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮长捧,結(jié)果婚禮上嚣鄙,老公的妹妹穿的比我還像新娘。我一直安慰自己串结,他們只是感情好哑子,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肌割,像睡著了一般卧蜓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上把敞,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天弥奸,我揣著相機(jī)與錄音,去河邊找鬼奋早。 笑死盛霎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的耽装。 我是一名探鬼主播愤炸,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼掉奄!你這毒婦竟也來了摇幻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤挥萌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后枉侧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體引瀑,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年榨馁,在試婚紗的時候發(fā)現(xiàn)自己被綠了憨栽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡翼虫,死狀恐怖屑柔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情珍剑,我是刑警寧澤掸宛,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站招拙,受9級特大地震影響唧瘾,放射性物質(zhì)發(fā)生泄漏措译。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一饰序、第九天 我趴在偏房一處隱蔽的房頂上張望领虹。 院中可真熱鬧,春花似錦求豫、人聲如沸塌衰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽最疆。三九已至,卻和暖如春是晨,著一層夾襖步出監(jiān)牢的瞬間肚菠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工罩缴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留蚊逢,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓箫章,卻偏偏與公主長得像烙荷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子檬寂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

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