2018-05-28 類別履肃、委托與協(xié)議

在有些時(shí)候仔沿,我們希望能夠用一些已經(jīng)封裝好的類,但又希望能夠加點(diǎn)自己想要的功能榆浓,但是很明顯于未,繼承并不適用于一些工具包或者類庫(kù),如NSString陡鹃,如果我們要給NSString加一個(gè)獲得長(zhǎng)度的方法該怎么辦呢烘浦?這時(shí)候就要用到“類別”了。

零.寫(xiě)在前面:類別與繼承

類別可以拓展一個(gè)類并添加額外的方法萍鲸,使得在不修改該類原先代碼的情況下闷叉,拓展或者修改現(xiàn)有類的定義,并且是向下有效的脊阴,會(huì)影響到該類的所有子類握侧。
重寫(xiě)一個(gè)類的方式用繼承還是分類取決于具體情況。

  • 假如目標(biāo)類有許多的子類嘿期,我們需要拓展這個(gè)類又不希望影響到原有的代碼品擎,繼承比較好。
  • 如果僅僅是拓展方法备徐,分類更好萄传。(不需要涉及到原先的代碼)

2.分類:用來(lái)擴(kuò)展類的方法,不能定義新成員蜜猾,但是可以訪問(wèn)到私有成員
子類:可以通過(guò)覆蓋和定義新方法來(lái)擴(kuò)展父類秀菱,可以新增成員,但是不能訪問(wèn)父類的私有成員蹭睡。

一.類別的創(chuàng)建與實(shí)現(xiàn)

1.創(chuàng)建

首先我們要聲明一下"NSString"的類別衍菱,注意在NSString后面加個(gè)括號(hào),只要保證類別名稱的唯一性肩豁,可以向一個(gè)類中添加任意多的類別:

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

@interface NSString(NumberConvenience)

-(NSNumber *) lengthAsNumber;

@end
//NSString.m
#import "NSString.h"

@implementation NSString (NumberConvenience)

- (NSNumber *) lengthAsNumber
{
    unsigned int length = (int) [self length];
    return [NSNumber numberWithUnsignedInt: length];
}

@end

2.實(shí)現(xiàn)

在Main.m里面調(diào)用該NSString:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject: [@"hello" lengthAsNumber] forKey:@"hello"];
[dict setObject: [@"Hoben" lengthAsNumber] forKey:@"Hoben"];
NSLog(@"%@", dict);

可以看到脊串,我們可以直接在NSString類后面添加lengthAsNumber方法。

3.局限性

  • 無(wú)法向類中添加新的實(shí)例變量蓖救,即類別沒(méi)有位置容納實(shí)例變量洪规。
  • 當(dāng)類別中的方法與現(xiàn)有的方法重名的時(shí)候,類別會(huì)具有更高的優(yōu)先級(jí)循捺,也就是說(shuō)斩例,我們創(chuàng)建的類別方法會(huì)完全取代初始方法,從而無(wú)法再使用初始方法从橘。(解決:在類別方法名中加一個(gè)前綴念赶,確保不發(fā)生名稱沖突础钠。)

二.類別的分散實(shí)現(xiàn)

我們可以將類別用于分散上面,即:將類的實(shí)現(xiàn)分散到多個(gè)不同文件或多個(gè)不同框架中叉谜,為什么要這樣做旗吁?舉個(gè)例子,NSString是Foundation框架中的一個(gè)類停局,包含了許多面向數(shù)據(jù)的類很钓,但APPKit也有一個(gè)NSString的類別,稱為NSStringDrawing董栽,該類別允許我們向字符串對(duì)象發(fā)送繪圖信息码倦。Cocoa的設(shè)計(jì)人員使用類別將數(shù)據(jù)功能放在Foundation中實(shí)現(xiàn),二將繪圖功能放在APPKit實(shí)現(xiàn)锭碳。作為編程人員袁稽,我們只需處理NSString即可,通常不用關(guān)心特定的方法來(lái)自何處擒抛。

1.寫(xiě)在前面的注意事項(xiàng)

分類可以擴(kuò)展類的方法推汽,但是不能新創(chuàng)建類的對(duì)象,也就是說(shuō)歧沪,用了分類之后歹撒,一切要使用的對(duì)象只能在父類中定義。(在本次實(shí)驗(yàn)中我遇到了@synthesize not allowed in a category's implementation的報(bào)錯(cuò)诊胞,所以特地提出來(lái)說(shuō)一下)

2.實(shí)現(xiàn)

這次的實(shí)驗(yàn)我們將CategoryThing分為Thing1栈妆、Thing2、Thing3來(lái)實(shí)現(xiàn)厢钧。

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

@interface CategoryThing : NSObject
@property (nonatomic, assign) int thing1;
@property (nonatomic, assign) int thing2;
@property (nonatomic, assign) int thing3;

@end
//CategoryThing.m
#import "CategoryThing.h"

@implementation CategoryThing

- (NSString *)description
{
    return [NSString stringWithFormat:@"%d %d %d",
            thing1,
            thing2,
            thing3];
}
@end

再用不同的類別寫(xiě)CategoryThing的get和set方法:

#import "CategoryThing.h"

@interface CategoryThing (Thing1)

- (void) setThing1: (int) thing1;
- (int) thing1;

@end
...//還有implementation

最后在main.m文件實(shí)現(xiàn):

CategoryThing *thing = [[CategoryThing alloc] init];
[thing setThing1: 3];
[thing setThing2: 5];
[thing setThing3: 7];

三.委托

protocol-協(xié)議,就是使用了這個(gè)協(xié)議后就要按照這個(gè)協(xié)議來(lái)辦事嬉橙,協(xié)議要求實(shí)現(xiàn)的方法就一定要實(shí)現(xiàn)早直。
delegate-委托,顧名思義就是委托別人辦事市框,就是當(dāng)一件事情發(fā)生后霞扬,自己不處理,讓別人來(lái)處理枫振。
當(dāng)一個(gè)A view 里面包含了B view
B view需要修改A view界面喻圃,那么這個(gè)時(shí)候就需要用到委托了。
需要幾個(gè)步驟:
1)首先定一個(gè)協(xié)議
2)A view實(shí)現(xiàn)協(xié)議中的方法
3)B view設(shè)置一個(gè)委托變量
4)把B view的委托變量設(shè)置成A view粪滤,意思就是斧拍,B view委托A view辦事情。
5)事件發(fā)生后杖小,用委托變量調(diào)用A view中的協(xié)議方法肆汹。

委托是一種對(duì)象愚墓,另一個(gè)類的對(duì)象會(huì)要求委托對(duì)象執(zhí)行它的某些操作。例如昂勉,當(dāng)APPKit類的NSApplication啟動(dòng)時(shí)浪册,他會(huì)詢問(wèn)其委托對(duì)象是否應(yīng)該打開(kāi)一個(gè)無(wú)標(biāo)題窗口。NSWindow類的對(duì)象詢問(wèn)它們自己的委托對(duì)象是否應(yīng)該允許關(guān)閉某個(gè)窗口岗照。
更常用的是村象,編寫(xiě)委托對(duì)象并將其提供給其他一些對(duì)象,通常是提供給Cocoa生成的對(duì)象攒至。通過(guò)實(shí)現(xiàn)特定的方法厚者,可以控制Cocoa中的對(duì)象的行為。
Cocoa中的滾動(dòng)列表是由APPKit類的NSTableView處理的嗓袱。當(dāng)tableView對(duì)象準(zhǔn)備好執(zhí)行某些操作(例如選擇用戶剛剛點(diǎn)擊的行)時(shí)籍救,它詢問(wèn)其委托對(duì)象是否選擇此行。tableView對(duì)象給其委托對(duì)象發(fā)送一條消息:

- (BOOL) tableView: (NSTableView *) tableView
         shouldSelectRow: (int) row;

委托方法可以查看tableView對(duì)象和行并確定是否應(yīng)該選擇該行渠抹。如果表中包含了不該選擇的行蝙昙,則委托對(duì)象可能禁用那些不被選擇的行。
現(xiàn)在以iTunesFinder項(xiàng)目為例梧却,告訴網(wǎng)絡(luò)服務(wù)瀏覽器你期待的服務(wù)并為其提供一個(gè)委托對(duì)象奇颠。然后,該瀏覽器對(duì)象將向委托對(duì)象發(fā)送消息放航,告知其發(fā)現(xiàn)新服務(wù)的時(shí)間烈拒。具體代碼如注釋所示。

NSNetServiceBrowser *browser;
browser = [[NSNetServiceBrowser alloc] init];
ITunesFinder *finder;
finder = [[ITunesFinder alloc] init];
//告訴網(wǎng)絡(luò)服務(wù)瀏覽器广鳍,使用ITunesFinder類的對(duì)象作為雙親委托
[browser setDelegate: finder];
//"_daap._tcp"告訴網(wǎng)絡(luò)服務(wù)瀏覽器使用TCP網(wǎng)絡(luò)協(xié)議去搜索DAAP(數(shù)字音頻訪問(wèn)協(xié)議)
//類型的服務(wù)荆几。該語(yǔ)句可以找出由iTunes發(fā)布的庫(kù)。
//域local.表示只在本地網(wǎng)絡(luò)中搜索該服務(wù)赊时。
[browser searchForServicesOfType: @"_daap._tcp"
                        inDomain: @"local."];
NSLog(@"begun browsing");
//run循環(huán)會(huì)一直處于阻塞狀態(tài)(不執(zhí)行任何處理)吨铸,直到某些有趣的事情發(fā)生為止。
//在本例中祖秒,有趣的事情是指網(wǎng)絡(luò)服務(wù)瀏覽器發(fā)現(xiàn)了新的iTunes共享诞吱。
[[NSRunLoop currentRunLoop] run];

在ITunesFinder類中,我們并不需要在@interface中聲明方法竭缝。要成為一個(gè)委托對(duì)象房维,我們只需實(shí)現(xiàn)已經(jīng)打算調(diào)用的方法。

//ITunesFinder.h
#import <Foundation/Foundation.h>
//這里還是要聲明一下該類是NSNetServiceBrowser的委托抬纸,否則會(huì)有warning
@interface ITunesFinder : NSObject <NSNetServiceBrowserDelegate>
@end
//ITunesFinder.m
@implementation ITunesFinder
-(void) netServiceBrowser: (NSNetServiceBrowser *) b
           didFindService:(nonnull NSNetService *)service
               moreComing:(BOOL)moreComing
{
    //當(dāng)NSNetServiceBrowser發(fā)現(xiàn)新服務(wù)時(shí)咙俩,他給委托對(duì)象發(fā)送netServiceBrowser:didFindService:moreComing:消息
    //瀏覽器被作為第一個(gè)參數(shù)(與main()函數(shù)中Browser變量的值相同)傳遞
    //如果有多個(gè)服務(wù)瀏覽器在同時(shí)進(jìn)行搜索,可以利用參數(shù)檢查計(jì)算出哪個(gè)瀏覽器發(fā)現(xiàn)了新服務(wù)松却。
    //NSNetService描述了被發(fā)現(xiàn)的服務(wù)(如ITunes共享)
    //moreComing用于指示一批通知是否已經(jīng)完成暴浦。
    [service resolveWithTimeout: 10];
    NSLog(@"found one! Name is %@", [service name]);
}

-(void) netServiceBrowser: (NSNetServiceBrowser *) b
           didRemoveService:(nonnull NSNetService *) service
               moreComing:(BOOL)moreComing
{
    //在某個(gè)服務(wù)不可再用的時(shí)候被調(diào)用溅话。
    [service resolveWithTimeout: 10];
    NSLog(@"lost one! Name is %@", [service name]);
}
@end

四.委托和類別

被發(fā)送給委托對(duì)象的方法可以聲明為一個(gè)NSObject的類別,如NSNetService委托方法的部分聲明如下:

#import <Foundation/Foundation.h>

@interface NSObject(NSNetServiceBrowserDelegateMethods)

- (void) netServiceBrowserWillSearch:
    (NSNetServiceBrowser *) browser;

- (void) netServiceBrowser: (NSNetServiceBrowser *) aNetServiceBrowser
            didFindService: (nonnull NSNetService *)service
                moreComing: (BOOL)moreComing;

- (void) netServiceBrowserDidStopSearch:
    (NSNetServiceBrowser *)browser;

- (void) netServiceBrowser: (NSNetServiceBrowser *) browser
            didRemoveService: (nonnull NSNetService *)service
                moreComing: (BOOL)moreComing;
@end

通過(guò)將這些方法聲明為NSObject的類別歌焦,NSNetServiceBrowser的實(shí)現(xiàn)可以將這些消息之一發(fā)送給任何對(duì)象飞几,無(wú)論這些對(duì)象實(shí)際上屬于哪個(gè)類。這也意味著独撇,只要對(duì)象實(shí)現(xiàn)了委托方法屑墨,任何類的對(duì)象都可以成為委托對(duì)象。
創(chuàng)建一個(gè)NSObject的類別成為“創(chuàng)建一個(gè)非正式協(xié)議”纷铣,即實(shí)現(xiàn)自己可能希望實(shí)現(xiàn)的方法卵史,使用它們更好地完成工作。之后如果想使用該方法搜立,則在main.m中綁定委托對(duì)象以躯,再在委托對(duì)象所在的類實(shí)現(xiàn)該方法,即可委托完成啄踊。

五.響應(yīng)選擇器

當(dāng)NSNetServiceBrowser試圖發(fā)送一個(gè)對(duì)象無(wú)法理解的消息的時(shí)候忧设,就會(huì)發(fā)生OC的運(yùn)行時(shí)錯(cuò)誤:selector not recognized。
解決:NSNetServiceBrowser首先檢查對(duì)象颠通,詢問(wèn)其能否響應(yīng)該選擇器址晕。如果對(duì)象能夠響應(yīng)該選擇器,NSNetServiceBrowser則給他發(fā)送消息顿锰。
如:

if ([browser respondsToSelector: 
@selector(netServiceBrowser:didFindService:moreComing:)])

如果該委托對(duì)象能夠響應(yīng)給定的消息谨垃,則瀏覽器向該對(duì)象發(fā)送此消息。否則硼控,瀏覽器將暫時(shí)忽略該委托對(duì)象刘陶,繼續(xù)正常運(yùn)行。

六.協(xié)議

正式協(xié)議是一個(gè)命名的方法列表牢撼。但與非正式協(xié)議不同的是易核,正式協(xié)議要求顯式地采用協(xié)議。即在類的@interface聲明中列出協(xié)議的名稱浪默。采用協(xié)議意味著承諾實(shí)現(xiàn)該協(xié)議的所有方法。否則缀匕,編譯器將會(huì)生成警告纳决。

1.聲明協(xié)議

我們聲明一個(gè)協(xié)議叫做NSCopying,如果采用該協(xié)議乡小,則對(duì)象將知道如何復(fù)制自己:

@protocol NSCopying

- (id) copyWithZone: (NSZone *) zone;
@end

這和interface有點(diǎn)像阔加,但區(qū)別在于:@protocol告訴編譯器:“下面將是一個(gè)新的正式協(xié)議”,@protocol之后是協(xié)議名稱满钟,協(xié)議名稱必須唯一胜榔。

2.復(fù)制

copy消息通知對(duì)象創(chuàng)建一個(gè)全新的對(duì)象胳喷,并使新對(duì)象與接收copy消息的原對(duì)象一樣。下面進(jìn)行Car的復(fù)制實(shí)驗(yàn):

//Engine.h
@interface Engine : NSObject <NSCopying>
//Engine.m
- (id) copyWithZone:(NSZone *)zone
{
    Engine *engineCopy;
    //首先通過(guò)[self class]獲得self對(duì)象所屬的類
    //然后通過(guò)allocWithZone分配內(nèi)存并創(chuàng)建一個(gè)該類的新對(duì)象
    //最后給新對(duì)象發(fā)送init消息使其初始化
    engineCopy = [[[self class] allocWithZone: zone] init];
    return engineCopy;
}
//Tire.h
@interface Tire : NSObject <NSCopying>
//Tire.m
- (id) copyWithZone:(NSZone *)zone
{
    Tire *tireCopy;
    tireCopy = [[[self class]
                 allocWithZone: zone]
                initPressure: _pressure andTreadDepth:_treadDepth];
    return tireCopy;
}

實(shí)現(xiàn)繼承的類的時(shí)候夭织,無(wú)需聲明<NSCopying>吭露,可以直接調(diào)用父類的方法。

//AllWeatherRadial.m
- (id) copyWithZone:(NSZone *)zone
{
    AllWeatherRadial *tireCopy;
    tireCopy = [super copyWithZone: zone];
    [tireCopy setRainHandling: _rainHandling];
    [tireCopy setSnowHandling: _snowHandling];
    return tireCopy;
}

復(fù)制Car本身:

- (id) copyWithZone:(NSZone *)zone
{
    Car *carCopy;
    carCopy = [[[self class] allocWithZone: zone] init];
    carCopy.name = self.name;
    Engine *engineCopy = [engine copy];
    carCopy.engine = engineCopy;
    
    for (int i = 0; i < 4; i++) {
        Tire *tireCopy;
        tireCopy = [[self tireAtIndex: i] copy];
        [carCopy setTire: tireCopy atIndex: i];
    }
    
    return carCopy;
}

在main.m這樣調(diào)用:

Car *carCopy = [car copy];
[carCopy print];

即可復(fù)制之前創(chuàng)建好的Car類實(shí)例尊惰。

3.協(xié)議與復(fù)制類型

我們可以在使用的數(shù)據(jù)類型中為實(shí)例變量和方法參數(shù)指定協(xié)議名稱讲竿,這樣就可以給OC的編譯器提供更多一點(diǎn)的信息,從而有助于檢查代碼中的錯(cuò)誤弄屡,如:

- (void) setObjectValue: (id<NSCopying>) obj;

編譯器將會(huì)直到期望的任意類型的對(duì)象题禀,只要其遵守該協(xié)議。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膀捷,一起剝皮案震驚了整個(gè)濱河市迈嘹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌全庸,老刑警劉巖秀仲,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異糕篇,居然都是意外死亡啄育,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門拌消,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挑豌,“玉大人,你說(shuō)我怎么就攤上這事墩崩∶ビⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵鹦筹,是天一觀的道長(zhǎng)铝阐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)铐拐,這世上最難降的妖魔是什么徘键? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮遍蟋,結(jié)果婚禮上吹害,老公的妹妹穿的比我還像新娘。我一直安慰自己虚青,他們只是感情好它呀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般纵穿。 火紅的嫁衣襯著肌膚如雪下隧。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天谓媒,我揣著相機(jī)與錄音淆院,去河邊找鬼。 笑死篙耗,一個(gè)胖子當(dāng)著我的面吹牛迫筑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宗弯,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼脯燃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蒙保?” 一聲冷哼從身側(cè)響起辕棚,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎邓厕,沒(méi)想到半個(gè)月后逝嚎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡详恼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年补君,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昧互。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挽铁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敞掘,到底是詐尸還是另有隱情叽掘,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布玖雁,位于F島的核電站更扁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赫冬。R本人自食惡果不足惜浓镜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劲厌。 院中可真熱鬧竖哩,春花似錦、人聲如沸脊僚。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辽幌。三九已至增淹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乌企,已是汗流浹背虑润。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留加酵,地道東北人拳喻。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像猪腕,于是被迫代替她去往敵國(guó)和親冗澈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,376評(píng)論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,100評(píng)論 1 32
  • 37.cocoa內(nèi)存管理規(guī)則 1)當(dāng)你使用new陋葡,alloc或copy方法創(chuàng)建一個(gè)對(duì)象時(shí)亚亲,該對(duì)象的保留計(jì)數(shù)器值為1...
    如風(fēng)家的秘密閱讀 843評(píng)論 0 4
  • 1.項(xiàng)目經(jīng)驗(yàn) 2.基礎(chǔ)問(wèn)題 3.指南認(rèn)識(shí) 4.解決思路 ios開(kāi)發(fā)三大塊: 1.Oc基礎(chǔ) 2.CocoaTouch...
    陽(yáng)光的大男孩兒閱讀 4,984評(píng)論 0 13
  • 梧桐葉落瀟雨 風(fēng)與誰(shuí)輕舞漸逝的錦瑟年華 回憶里仍憶起撐著油紙傘 走過(guò)的青石板陌 跫音如春雨錯(cuò)落于芭蕉葉 渺渺紅塵 ...
    琦雪冰凝閱讀 296評(píng)論 0 5