重學(xué)iOS——1.從C角度看OC

面向?qū)ο?/h6>

面向?qū)ο蟮木幊趟季S壁晒,簡而言之就是:一切皆對象秒咐。面向?qū)ο蟮恼Z言區(qū)別于C語言(面向過程)携取,C語言是按照代碼的執(zhí)行順序去實(shí)現(xiàn)項(xiàng)目功能雷滋,而高級編程語言是從對象的角度去把控文兢,詳細(xì)解釋就是:任何事件都是由事物構(gòu)成姆坚,事物擁有自己特有的屬性(對象的固有屬性和行為屬性),大事件通過各種事物之間的相互作用(行為調(diào)用)實(shí)現(xiàn)兔辅。OC是從C語言的基礎(chǔ)之上發(fā)展而來的维苔,是C語言的面向?qū)ο蠼槭薄C完全兼容C語言潮尝,可以實(shí)現(xiàn)OC與C的混合編程饿序,一起生成可執(zhí)行文件原探。

OC與C的部分不同點(diǎn)

參考代碼:

#import <Foundation/Foundation.h>
#import <objc/objc.h>

/*
 *要求定義一個人類
 *事物名稱:人
 *屬性:年齡(age),身高(height)咽弦,體重(weight)
 *行為:吃飯(eat),睡覺(sleep),散步(walk)
 */

@interface Person : NSObject
{
    @public
    //屬性
    int _age;
    double _height;
    double _weight;
}
//行為
-(void)eat:(char *)food;

-(void)sleep;

-(void)walk;
+(void)about;
@end


@implementation Person

-(void)eat:(char *)food
{
    NSLog(@"吃%s",food);
}

-(void)walk
{
    NSLog(@"開始遛彎");
}

-(void)sleep
{
    NSLog(@"開始睡覺");
}

+(void)about
{
    NSLog("Hello");
}
@end


int main(int argc, const char * argv[]) {
    //1. 通過類創(chuàng)建對象
    /*
     *1.開辟存儲空間
     *2.初始化所有屬性
     *3.返回指針地址
     */

    //因?yàn)樵诙褩V袆?chuàng)建的對象段审,實(shí)質(zhì)是一個結(jié)構(gòu)體闹蒜,所以可以通過結(jié)構(gòu)體指針直接訪問屬性
    /*
     *創(chuàng)建對象的時候绷落,返回的地址其實(shí)就是類的第0個屬性的地址
     *結(jié)構(gòu)體創(chuàng)建完成以后,結(jié)構(gòu)體的地址其實(shí)就是結(jié)構(gòu)體第0個成員的首地址
     *但是需要注意的是:類的第0個屬性并不是我們編寫的_age筐喳,而是一個叫做isa的屬性
     *isa是一個指針避归,占8個字節(jié)
     *
     *其實(shí)類也是一個對象梳毙,也就意味著Person也是一個對象
     *平時我們所說的創(chuàng)建對象顿天,就是通過一個類對象創(chuàng)建一個新的對象
     *類對象是系統(tǒng)自動幫我們創(chuàng)建的蔑担,里面保存了當(dāng)前對象的所有方法啤握,準(zhǔn)確說是一個方法列表排抬,包括方法體
     *而實(shí)際對象是程序自己員手動通過new來創(chuàng)建的,而實(shí)例對象中有一個isa指針就指向了創(chuàng)建它的那個類對象
     */
    Person *p=[Person new];
    p->_age=30;
    p->_height=1.75;
    p->_weight=65.0;
    [p walk];
    [Person about];
    NSLog(@"p=%p",p);
    NSLog(@"&age=%p",&(p->_age));
    /*
     *結(jié)構(gòu)體創(chuàng)建完成以后番甩,結(jié)構(gòu)體的地址其實(shí)就是結(jié)構(gòu)體第0個成員的首地址
     */
    //    struct Person
    //    {
    //        int age;
    //        char *name;
//    };
//    struct Person sp;
//    NSLog(@"&sp=%p",&sp);
//    NSLog(@"&age=%p",&sp.age);
    return 0;
}

1.#import和#include的區(qū)別
import的功能和include的功能是一樣的缘薛,都是導(dǎo)入文件,但是OC為了避免C語言中的重復(fù)導(dǎo)入問題(避免使用復(fù)雜的頭文件衛(wèi)士)為import集成了避免重復(fù)導(dǎo)入的機(jī)制漱抓。下面介紹一下C語言中頭文件衛(wèi)士的寫法:

#ifndef _TEST_H
#define _TEST_H//一般是文件名的大寫
頭文件結(jié)尾寫上一行:
#endif

這樣一個工程文件里同時包含兩個test.h時乞娄,就不會出現(xiàn)重定義的錯誤了仪或。
分析:當(dāng)?shù)谝淮伟瑃est.h時追迟,由于沒有定義_TEST_H敦间,條件為真,這樣就會包含(執(zhí)行)#ifndef _TEST_H和#endif之間的代碼厢绝,當(dāng)?shù)诙伟瑃est.h時前面一次已經(jīng)定義了_TEST_H昔汉,條件為假靶病,#ifndef _TEST_H和#endif之間的代碼也就不會再次被包含口予,這樣就避免了重定義了沪停。
當(dāng)然以上這些內(nèi)容都是關(guān)于C語言-預(yù)處理的知識內(nèi)容木张,具體細(xì)節(jié)參考:C語言再學(xué)習(xí)——C預(yù)處理器和頭文件為什么要加#ifndef #define #endif

2.OC實(shí)現(xiàn)面向?qū)ο蟮脑?br> OC是對C語言進(jìn)行了面向?qū)ο蟮姆庋b,即通過C語言實(shí)現(xiàn)面向?qū)ο缶槌梗敲词侨绾螌?shí)現(xiàn)的蛛株?其實(shí)是結(jié)構(gòu)體+指針的方式實(shí)現(xiàn)的。OC中的對象在內(nèi)存中其實(shí)是以結(jié)構(gòu)體的形式進(jìn)行存儲的。這一點(diǎn)的內(nèi)容就涉及到了runtime運(yùn)行時的內(nèi)容屉符。在這里由于目前還沒有涉及到運(yùn)行時內(nèi)容锹引,所以對本部分內(nèi)容進(jìn)行了適當(dāng)?shù)暮喕颖洌瑫r也增進(jìn)了后期運(yùn)行時內(nèi)容的進(jìn)一步學(xué)習(xí)與理解。
OC中的對象是通過結(jié)構(gòu)體來實(shí)現(xiàn)的东涡,即在堆中對象的存儲數(shù)據(jù)結(jié)構(gòu)是struct疮跑,創(chuàng)建的對象變量祖娘,其實(shí)是一個指向相應(yīng)類結(jié)構(gòu)體的指針啊奄。由于對象的實(shí)際結(jié)構(gòu)是結(jié)構(gòu)體菇夸,那么我們可以通過"->”這樣的方式去訪問實(shí)例對象中的屬性峻仇,代碼如下:

IPhone *p=[IPhone new];
p->_color=0;//默認(rèn)@interface中的屬性都是@protected的,如果想這樣子直接訪問凡蚜,需要使用@public
p->_model=0;

在實(shí)際的實(shí)例對象存儲過程中朝蜘,實(shí)例對象內(nèi)部是不存在實(shí)例方法的谱醇,只包含屬性信息和isa指針信息,isa指針指向該類的類對象奈附,類對象是在程序編譯階段煮剧,系統(tǒng)自動創(chuàng)建的勉盅,包含了類的所有信息(屬性列表、方法列表挑胸、類名等信息)茬贵,是創(chuàng)建實(shí)例對象的依據(jù)(模板)闷沥。需要注意的是:結(jié)構(gòu)體創(chuàng)建完成以后咐容,結(jié)構(gòu)體的地址其實(shí)就是結(jié)構(gòu)體第0個成員的首地址戳粒,但是類對象的首地址是isa指針屬性的存儲值,isa是一個指針奄妨,占8位苹祟。具體在內(nèi)存中的存在方式如下圖所示:

對象創(chuàng)建過程.png

所以從上圖中我們可以聯(lián)想到砸抛,[Person new]方法树枫,其實(shí)是調(diào)用了Person類對象的new方法。參考代碼中的[p walk]和 [Person about]對比會發(fā)現(xiàn)奔誓,類方法的執(zhí)行效率高于實(shí)例方法厨喂。圖解如下:

[p walk]分析.png
[Person about]分析.png

兩幅圖的分析蜕煌,故意將元類的概念略去,因?yàn)轭惙椒▽?shí)際是存儲在元類中的颁褂,但是在此為了方便理解,同時也為后期進(jìn)階做準(zhǔn)備彩届。
上圖中涉及到了堆樟蠕、棧、代碼區(qū)等內(nèi)容吓懈,具體可以參考iOS中的內(nèi)存管理C語言中內(nèi)存分配linux內(nèi)存管理深入淺出-iOS內(nèi)存分配與分區(qū)

3.OC中的類方法和實(shí)例方法以及函數(shù)
OC和C中的函數(shù)的對比耻警,其實(shí)很簡單甘穿,在這里直接上代碼温兼,我覺得對于身為程序員的自己來說武契,可能會更加清晰咒唆,注意點(diǎn):在Java中對象可以直接調(diào)用類方法,但是在OC中對象不能調(diào)用類方法敦腔,必須通過類調(diào)用類方法符衔。靜態(tài)方法、類方法和對象方法的區(qū)別

//
//  main.m
//  OC_day1_04_類方法
//
//  Created by 劉旭輝 on 2017/10/13.
//  Copyright ? 2017年 劉旭輝. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef enum
{
    KIColorBlace,//黑色
    KIColorWhite,//白色
    KIColorTuHaoJin//土豪金
}IColor;
//1.編寫類的聲明
@interface IPhone : NSObject
{
@public
    double _size;
//    int _color; //顏色 0代表黑色 1代表白色 2代表土豪金
    int _cpu;
    int _model;
    IColor _color;
}
/*
 *行為
 *OC中的行為和C語言中的函數(shù)一樣躺盛,都是用來保存一段特定功能的代碼
 *OC中定義一個方法槽惫,也分為聲明和實(shí)現(xiàn)辩撑,聲明在@interface中合冀,實(shí)現(xiàn)寫在@implementation
 *
 *C語言中的函數(shù)分為兩種:內(nèi)部函數(shù)和外部函數(shù)
 *OC中的函數(shù)也分為兩種:類方法和對象方法
 *類方法只能用類名調(diào)用,對象方法只能用對象調(diào)用
 *OC中的類方法用+表示峭判,OC中的對象方法用-表示
 *
 *編寫C語言函數(shù)的規(guī)律:1.確定函數(shù)名稱林螃;2.確定形參疗认;3.確定返回值伏钠;4.確定返回值類型
 *編寫OC方法也有規(guī)律贝润,規(guī)律和C語言一模一樣
 */

/*C語言方法
 void about();
 void about()
 {
     printf("model=cpu=size=color");
 }
 */

//注意:OC中的方法,如果沒有形參不需要寫()华畏,而是直接寫一個亡笑;
//為什么OC中沒有形參不需要寫()呢仑乌?因?yàn)镺C方法中的()有特殊用途,OC方法中的()是用來括住數(shù)據(jù)類型的
//行為的聲明
-(void)about;

/*
 *C語言中的函數(shù):1.沒有返回值沒有參數(shù)的函數(shù)衙传;2.有返回值沒有參數(shù)的蓖捶;3.有返回值有參數(shù)的俊鱼;4.沒有返回值有參數(shù)的
 *OC中的方法也有四種
 */

//有返回值沒有參數(shù)的畅买。例如:讀取短信
-(char *)loadMessage;

//有返回值有參數(shù)的谷羞,例如:打電話
//int signal(int number); C語言中的函數(shù)
//注意:OC中的方法如果有參數(shù),那么每個參數(shù)的數(shù)據(jù)類型前面必須加一個:
//注意:當(dāng)前的有參數(shù)的方法的方法名稱是  signal: 冒號也是方法名稱的一部分
-(int)signal:(int)number;

//有返回值,并且有多個參數(shù)的雁歌,發(fā)短信
//int sendMessage(int number,char* content);
//為了提高閱讀性知残,OC方法允許我們給每一個參數(shù)添加一個標(biāo)簽來說明當(dāng)前參數(shù)的含義
-(int)sendMessageWithNumber:(int)number andContent:(char*) content;
//-(int)sendMessage:(int)number :(char*) content; //當(dāng)前的方法名稱叫做:sendMessage::

//沒有返回值求妹,有參數(shù)的函數(shù)
-(void)callWithNumber:(int) number;


//計算器功能(類方法)
//如果你不想每次使用方法都需要創(chuàng)建對象并且開辟存儲空間
//并且如果該方法中沒有使用到屬性(成員變量),那么你可以把這個方法定義為類方法
//對象方法用對象調(diào)用 類方法用類名調(diào)用
//-(int)sumWithNumber1:(int)number1 andNumber2:(int) number2;
//只需要將對象方法的-號轉(zhuǎn)換成+制恍,那么就定義了一個類方法
//注意:如果實(shí)現(xiàn)了一個類方法,就必須去實(shí)現(xiàn)類方法
//如果實(shí)現(xiàn)的是一個對象方法何吝,那么就必須去實(shí)現(xiàn)對象方法




/*
 *類方法和對象方法的區(qū)別
 *0.對象方法以-開頭爱榕;類方法以+開頭
 *1.對象方法必須用對象調(diào)用黔酥,類方法必須用類調(diào)用
 *2.對象方法中可以直接訪問屬性(成員變量),類方法中不可以直接訪問屬性(成員變量)
 *3.類方法的優(yōu)點(diǎn)棵帽,調(diào)用類方法的效率會比調(diào)用對象方法高
 *4.類方法和對象方法可以進(jìn)行相互調(diào)用
 *4.1對象方法中可以直接調(diào)用類方法
 *4.2可以在類方法中間接調(diào)用對象方法
 *4.3在類方法中可以直接調(diào)用其他方法
 *4.4對象方法中可以直接調(diào)用對象方法
 */


/*
 *類方法的應(yīng)用場景
 *如果方法中沒有使用到屬性(成員變量)岖寞,那么能用類方法就用類方法
 *類方法的執(zhí)行效率比對象方法高
 *
 *類方法一般用于定義工具方法
 *字符串查找
 *文件操作
 *數(shù)據(jù)庫操作
 */
+(int)sumWithNumber1:(int)number1 andNumber2:(int) number2;
@end

//2.編寫類的實(shí)現(xiàn)
@implementation IPhone
//行為的實(shí)現(xiàn)
-(void)about
{
    //    NSLog(@"打印本機(jī)信息");
    //如果在對象方法中想訪問該對象的屬性仗谆,可以直接寫上_屬性名稱即可
    [IPhone sumWithNumber1:50 andNumber2:50];
    NSLog(@"size=%f,color=%i,model=%i,cpu=%i",_size,_color,_model,_cpu);
}

-(char *)loadMessage
{
      return "老婆我們家我做主";
 }

-(int)signal:(int)number
{
    NSLog(@"打電話給%i",number);
    return 1;
}

-(int)sendMessage:(int)number :(char *)content
{
    NSLog(@"發(fā)短信給%i,內(nèi)容是%s",number,content);
    return 0;
}

-(int)sendMessageWithNumber:(int)number andContent:(char *)content
{
    NSLog(@"發(fā)短信給%i,內(nèi)容是%s",number,content);
    return 0;
}
-(void)callWithNumber:(int)number
{
    NSLog(@"打電話給%i",number);
}

+(int)sumWithNumber1:(int)number1 andNumber2:(int)number2
{
    IPhone *p1=[IPhone new];
    [p1 about];//在類方法中隶垮,可以簡介調(diào)用對象方法狸吞,但是在企業(yè)開發(fā)中指煎,不建議這樣子使用
    return number1+number2;
}

@end
int main(int argc, const char * argv[]) {
    //1.通過類創(chuàng)建對象
    IPhone *p=[IPhone new];
    p->_color=KIColorBlace;
    p->_model=4;
    p->_cpu=1;
    p->_size=3.5;
    //3.獲取對象的屬性
    //    NSLog(@"size=%f,color=%i,model=%i,cpu=%i",p->_size,p->_color,p->_model,p->_cpu);
    //4.如果給對象發(fā)消息(如果調(diào)用對象的方法)
    [p about];
    //注意:OC中的NSLog對C語言中的字符串支持不是很好至壤,如果返回的是中文的C語言字符串可能輸出是亂碼像街,也可能什么都不輸出
    NSLog(@"%s",[p loadMessage]);
    [IPhone sumWithNumber1:1 andNumber2:2];
    //    [p sendMessage:110 :"help,help"];
    [p sendMessageWithNumber:110 andContent:"help"];
    [p sendMessage:110 :"help,help"];
    [p signal:110];
    [p callWithNumber:119];
    return 0;
}

void test()
{
    //1.創(chuàng)建一個對象
    IPhone *p1=[IPhone new];
    //2.利用對象調(diào)用假發(fā)運(yùn)算方法
//    [p1 sumWithNumber1:1 andNumber2:2];
}

4.OC成員變量镰绎、局部變量、全局變量的區(qū)別以及內(nèi)存分析

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    //寫在類聲明的大括號中的變量随静,我們稱之為成員變量(或者屬性挪挤,實(shí)例變量)
    //注意:
    //1.成員變量不能離開類关翎,離開類以后就不是成員變量纵寝;
    //2.成員變量不能在定義的同時進(jìn)行初始化星立;
    //3.成員變量只能通過對象來訪問
    //存儲在:堆(當(dāng)前對應(yīng)的堆的內(nèi)存空間中)
    //存儲在堆中的數(shù)據(jù)绰垂,不會被自動釋放劲装,只能程序員手動釋放
    int age;
}

@end

@implementation Person



@end
//寫在函數(shù)和大括號外部的變量占业,我們稱之為全局變量
//作用域:從定義的那一行開始纯赎,一直到文件末尾
//全局變量可以先定義再初始化犬金,也可以定義的同時初始化
//存儲在:靜態(tài)區(qū)
//程序一啟動就會分配內(nèi)存空間,知道程序結(jié)束才會釋放
int a;
int b=10;
int main(int argc, const char * argv[]) {
    //寫在函數(shù)或者代碼塊中的變量峰伙,我們稱之為局部變量
    //作用域:從定義的哪一行開始瞳氓,一直到遇到大括號或者return
    //局部變量可以先定義再初始化权均,也可以定義的同時初始化
    //存儲在棧中
    //存儲在棧中的數(shù)據(jù)有一個特點(diǎn)叽赊,系統(tǒng)會自動給我們釋放
    int num=10;
    return 0;
}
#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    //寫在類聲明的大括號中的變量必指,我們稱之為成員變量(或者屬性塔橡,實(shí)例變量)
    //注意:
    //1.成員變量不能離開類霜第,離開類以后就不是成員變量;
    //2.成員變量不能在定義的同時進(jìn)行初始化癞谒;
    //3.成員變量只能通過對象來訪問
    //存儲在:堆(當(dāng)前對應(yīng)的堆的內(nèi)存空間中)
    //存儲在堆中的數(shù)據(jù)弹砚,不會被自動釋放桌吃,只能程序員手動釋放
    int age;
}

@end

@implementation Person



@end
//寫在函數(shù)和大括號外部的變量,我們稱之為全局變量
//作用域:從定義的那一行開始逗物,一直到文件末尾
//全局變量可以先定義再初始化敬察,也可以定義的同時初始化
//存儲在:靜態(tài)區(qū)
//程序一啟動就會分配內(nèi)存空間尔当,知道程序結(jié)束才會釋放
int a;
int b=10;
int main(int argc, const char * argv[]) {
    //寫在函數(shù)或者代碼塊中的變量椭迎,我們稱之為局部變量
    //作用域:從定義的哪一行開始,一直到遇到大括號或者return
    //局部變量可以先定義再初始化缴阎,也可以定義的同時初始化
    //存儲在棧中
    //存儲在棧中的數(shù)據(jù)有一個特點(diǎn)蛮拔,系統(tǒng)會自動給我們釋放
    int num=10;
    return 0;
}

在以上的代碼中已經(jīng)對成員變量建炫、全局變量疼蛾、局部變量做了詳細(xì)的區(qū)分,但是在內(nèi)存中具體是如何存儲的察郁?還沒有一個明確的概念。通過閱讀一些博客稳捆,對物理存儲有了一定的了解眷柔,分析如下:

  • RAM和ROM區(qū)分
    我們所說的內(nèi)存,其實(shí)指的就是RAM驯嘱,在程序運(yùn)行期間系統(tǒng)將ROM中的源代碼加載到RAM中鞠评,我們所說的棧、堆聋涨、全局區(qū)/靜態(tài)區(qū)牍白、常量區(qū)抖棘、代碼區(qū)其實(shí)都是位于RAM中切省。

    RAM:運(yùn)行內(nèi)存,不能掉電存儲般渡。
    ROM:存儲性內(nèi)存驯用,可以掉電存儲儒老,例如內(nèi)存卡、Flash淘这。
    由于RAM類型不具備掉電存儲能力(即一掉電數(shù)據(jù)消失)巩剖,所以app程序一般存放于ROM中佳魔。RAM的訪問速度要遠(yuǎn)高于ROM鞠鲜,價格也要高。App程序啟動榆苞,系統(tǒng)會把開啟的那個App程序從Flash或ROM里面拷貝到內(nèi)存(RAM)霞捡,然后從內(nèi)存里面執(zhí)行代碼碧信。另一個原因是CPU不能直接從內(nèi)存卡里面讀取指令(需要Flash驅(qū)動等等)。

  • RAM中五大分區(qū)詳解

  1. 棧區(qū)(stack):
    存放的局部變量躏筏、先進(jìn)后出趁尼、一旦出了作用域就會被銷毀碴卧;函數(shù)跳轉(zhuǎn)地址住册,現(xiàn)場保護(hù)等;
    程序猿不需要管理?xiàng)^(qū)變量的內(nèi)存凡人。主要負(fù)責(zé)函數(shù)模塊內(nèi)申請挠轴,函數(shù)結(jié)束時自動釋放岸晦,存放局部變量睛藻,函數(shù)變量
    ~棧區(qū)地址從高到低分配;
  2. 堆區(qū)(heap):
    通過malloc函數(shù)或new函數(shù)等操作符操作的得到冈在,需要程序員自己管理
    ARC的內(nèi)存的管理包券,是編譯器再便宜的時候自動添加 retain、release付秕、autorelease侍郭;
    ~堆區(qū)的地址是從低到高分配
  3. 全局區(qū)/靜態(tài)區(qū)(static):
    包括兩個部分:未初始化過(.bss段區(qū)域) 励幼、初始化過(data段區(qū)域),即全局區(qū)/靜態(tài)區(qū)在內(nèi)存中是放在一起的有滑,初始化的全局變量和靜態(tài)變量在一塊區(qū)域毛好, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域肌访。
  4. 常量區(qū):存放常量字符串艇劫;
  5. 代碼區(qū): 存放編寫的源代碼店煞,由系統(tǒng)自動加載進(jìn)入;
  6. 注意:也有人將全局區(qū)/靜態(tài)區(qū)(static)和常量區(qū)聯(lián)合在一起成為數(shù)據(jù)區(qū)酒请。

具體圖示如下圖所示:

內(nèi)存分區(qū)圖解

5.函數(shù)與方法的區(qū)別
首先需要理解的一點(diǎn)是:方法是對象的行為羞反,函數(shù)是整個文件的一個功能塊昼窗。方法只能存在于類內(nèi)部阁将,函數(shù)可以存在于整個文件的任何地方做盅。具體代碼如下:

#import <Foundation/Foundation.h>


/*
 *函數(shù)和方法的區(qū)別
 *1.函數(shù)屬于整個文件,方法屬于某一個類亭敢,方法如果離開類就不行
 *2.函數(shù)可以直接調(diào)用图筹,方法必須用對象或者類來調(diào)用
 *注意:雖然函數(shù)屬于整個文件,但是如果把函數(shù)寫在類的聲明中就會不識別
 *3.不能把函數(shù)當(dāng)做方法調(diào)用远剩,也不能將方法當(dāng)做函數(shù)調(diào)用
 *
 *
 *方法的注意點(diǎn):
 *方法可以只有聲明沒有實(shí)現(xiàn)瓜晤,也可以只有實(shí)現(xiàn)沒有聲明痢掠,編譯不會報錯,但是運(yùn)行會報錯
 *如果方法只有聲明而沒有實(shí)現(xiàn)雄驹,則會報錯:1.reason:'+[Person demo]:unrecognized selector sent to class 0x100001140',發(fā)送了一個不能識別的消息淹辞,在Person類中沒有+開頭的方法
 *reason:'-[Person test]:unrecognized selector sent to instance 0x100001140'
 *類也可以只有實(shí)現(xiàn)沒有聲明,例如:@implementation Person : NSObjec ... @end
 */

@interface Person : NSObject
//對象方法的聲明
-(void)test;
//類方法聲明
+(void)demo;
@end

@implementation Person
//對象方法的實(shí)現(xiàn)
-(void)test
{
    NSLog(@"test");
}
//類方法的實(shí)現(xiàn)
+(void)demo
{
    NSLog(@"demo");
}

@end
//外部函數(shù)的聲明
extern void sum();
//內(nèi)部函數(shù)的聲明
static void minus();
//外部函數(shù)
extern void sum()
{
    printf("sum");
}
//內(nèi)部函數(shù)
static void minus()
{
    printf("minus");
}

int main(int argc, const char * argv[]) {
    
    return 0;
}

6.結(jié)構(gòu)體作為對象屬性的細(xì)節(jié)
當(dāng)結(jié)構(gòu)體作為函數(shù)(C語言中的稱呼)參數(shù)或者作為對象屬性的情況下彬向,結(jié)構(gòu)體是以拷貝結(jié)構(gòu)體屬性的方式進(jìn)行傳遞的娃胆,此過程傳遞的不是指針里烦。
結(jié)構(gòu)體作為屬性的代碼示例:
類模型

#import <Foundation/Foundation.h>

/*
 *合理的設(shè)計一個“學(xué)生”類
 *學(xué)生有*姓名*生日另個屬性和說出自己姓名生日的方法
 *要求利用設(shè)計的學(xué)生類創(chuàng)建學(xué)生對象禁谦,并且說出自己的姓名和年齡
 */

//定義一個新類型Date
typedef struct
{
    int year;
    int month;
    int day;
}Date;

@interface Student : NSObject
{
    @public
    NSString *_name;
    
    Date _birthday;
}
-(void)say;
@end

@implementation Student

-(void)say
{
    NSLog(@"name=%@;year=%i,month=%i,day=%i",_name,_birthday.year,_birthday.month,_birthday.day);
}

@end

結(jié)構(gòu)體屬性修改范例

int main(int argc, const char * argv[]) {
    //1.創(chuàng)建學(xué)生對象
    Student *student=[Student new];
    [student say];
    //2.設(shè)置學(xué)生對象的屬性
    student->_name=@"lxh";
    /*
     *student->_birthday={1992,12,23};錯誤原因
     *1.結(jié)構(gòu)體只能在定義的時候初始化
     *2.系統(tǒng)并不清楚它({1992,12,23})是數(shù)組還是結(jié)構(gòu)體
     */
    student->_birthday=(Date){1992,12,23};
    //student->_birthday=(Date){1992,12,23};這句話的本質(zhì)其實(shí)是:結(jié)構(gòu)體拷貝州泊,將結(jié)構(gòu)體{1992遥皂,12刽漂,23}強(qiáng)制拷貝給了_birthday
    /*
    Date d1={1999,1,5};
    Date d2;
    d2=d1; //當(dāng)結(jié)構(gòu)體作為函數(shù)的參數(shù)的時候贝咙,賦值其實(shí)是將結(jié)構(gòu)體內(nèi)部的屬性庭猩,進(jìn)行了一次拷貝
           //這里是將d1內(nèi)部的屬性都拷貝了一份賦值給了d2
    d2.year=2000;//修改d2的值并不影響d1的值
    printf("d1=year=%i\n",d1.year);
    printf("d2=year=%i\n",d2.year);
    */
    
    /*
     *這種方式賦值也可以陈症,單個賦值
     */
    student->_birthday.year=1992;
    student->_birthday.month=12;
    student->_birthday.day=23;
    
    /*
     *第三種賦值方式
     */
    Date d={1992,12,23};
    student->_birthday=d;
    return 0;
}

歡迎關(guān)注我的個人微信公眾號,免費(fèi)送計算機(jī)各種最新視頻資源徙缴!你想象不到的精彩于样!


0.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末穿剖,一起剝皮案震驚了整個濱河市糊余,隨后出現(xiàn)的幾起案子单寂,更是在濱河造成了極大的恐慌宣决,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件威沫,死亡現(xiàn)場離奇詭異棒掠,居然都是意外死亡烟很,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門恤筛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人妻枕,你說我怎么就攤上這事÷判常” “怎么了愕掏?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長剑梳。 經(jīng)常有香客問我垢乙,道長追逮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮眼滤,結(jié)果婚禮上诅需,老公的妹妹穿的比我還像新娘。我一直安慰自己毡证,他們只是感情好蔫仙,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布恤煞。 她就那樣靜靜地躺著,像睡著了一般概漱。 火紅的嫁衣襯著肌膚如雪瓤摧。 梳的紋絲不亂的頭發(fā)上玉吁,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天进副,我揣著相機(jī)與錄音影斑,去河邊找鬼。 笑死塞俱,一個胖子當(dāng)著我的面吹牛吏垮,可吹牛的內(nèi)容都是我干的膳汪。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼粘我,長吁一口氣:“原來是場噩夢啊……” “哼征字!你這毒婦竟也來了娇豫?” 一聲冷哼從身側(cè)響起冯痢,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咪辱,沒想到半個月后椎组,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年灵份,在試婚紗的時候發(fā)現(xiàn)自己被綠了填渠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸟辅。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡氛什,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匪凉,到底是詐尸還是另有隱情枪眉,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布再层,位于F島的核電站贸铜,受9級特大地震影響来农,放射性物質(zhì)發(fā)生泄漏萧诫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一盲再、第九天 我趴在偏房一處隱蔽的房頂上張望棍鳖。 院中可真熱鬧渡处,春花似錦、人聲如沸登下。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绽左,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鲁纠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹃觉,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像抽减,于是被迫代替她去往敵國和親颠锉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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