真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

iOS—EffectiveObjective—C2.0(1)-創(chuàng)新互聯(lián)

文章目錄
  • 了解OC起源
    • 消息結(jié)構(gòu)和函數(shù)調(diào)用之間的區(qū)別
    • 要點
      • 虛方法表
  • 在類頭文件中盡量少引入其他頭文件
    • 要點
  • 多用字面量語法,少用與之等價的方法
    • 字面量數(shù)值
    • 字面量數(shù)組
    • 字面量字典
    • 可變數(shù)組與字典:
    • 局限性:

成都創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、南譙網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、html5購物商城網(wǎng)站建設(shè)、集團公司官網(wǎng)建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為南譙等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。了解OC起源

面向?qū)ο笳Z言O(shè)C,在語法上使用的是“消息結(jié)構(gòu)”,而非“函數(shù)調(diào)用”

消息結(jié)構(gòu)和函數(shù)調(diào)用之間的區(qū)別
//messaging(OC)
object* obj = [object new];
[obj performWith:parameter1 and:parameter2]; 
//function calling (C++)
object* obj = new object;
obj ->perform(parameter1, parameter2);

關(guān)鍵區(qū)別:使用消息結(jié)構(gòu)的語言,其運行時所應(yīng)執(zhí)行的代碼由運行環(huán)境來決定;而使用函數(shù)調(diào)用的語言則由編譯器來決定。如果范例代碼中調(diào)用的函數(shù)是多態(tài)的,那么在運行時就要按照“虛方法表”來查出到底應(yīng)該執(zhí)行哪個函數(shù)實現(xiàn)。而采用消息結(jié)構(gòu)的語言,不論是否多態(tài),總是在運行時才會去查找所要執(zhí)行的方法實際上,編譯器不關(guān)心接受消息的對象是何種勒烯女。接收消息的對象問題也要在運行時候處理,其過程叫做“動態(tài)綁定”
OC的重要工作都由“運行期組件”而非編譯器來完成。使用OC的面向?qū)ο筇匦运璧娜繑?shù)據(jù)結(jié)構(gòu)及函數(shù)都在運行期組件李敏啊。舉例來說,運行期組件中含有全部的管理內(nèi)存的方法。運行期組件本質(zhì)上就是一種與開發(fā)者所編代碼相鏈接的“動態(tài)庫”,其代碼能把開發(fā)者編寫的所有程序粘合起來。這樣的話,只需要更新運行期組件,即可提升應(yīng)用程序性能。而那種許多工作都需要在“編譯期”完成的語言,若是想要獲得類似的性能提升,則需要重新編譯應(yīng)用程序代碼。
OC是C的“超集”所以c語言中的所有功能在編寫OC代碼的時候依然適用。因此必須同時掌握C與OC這兩門語言的核心概念,才能寫出高效的OC代碼來。
其中尤為重要的是要理解C語言的內(nèi)存模型,這有利于理解OC的內(nèi)存模型及“引用計數(shù)”機制的工作原理。
理解內(nèi)存模型:OC中的指針是用來指示對象的,想要聲明一個變量,令其指代某個對象,可用以下語法
NSString* someString = @"THE String";
這種語法基本上是照搬c語言的,他聲明了一個名為someString的變量,類型為NSString*也就是說,此變量為指向NSString的指針,所有OC語言的對象都必須這樣聲明,因為所占的內(nèi)存總是分配在“堆空間”中,而絕不會分配在“棧上”,不能在棧上分配OC對象
在這里插入圖片描述

someString變量指向分配在堆里的某塊內(nèi)存,其中含有一個NSString對象。也就是說,如果再創(chuàng)建一個變量,令其指向同一地址,那么并不拷貝該對象,只是這兩個變量會同時指向此對象
在這里插入圖片描述
這說明當前“棧幀”里面分配了兩塊內(nèi)存,每塊內(nèi)存的大小都能容下一枚指針(32位4字節(jié),64位8字節(jié))。兩塊內(nèi)存里面的值是一樣的,就是NSString實例的內(nèi)存地址
在這里插入圖片描述
分配在堆中的內(nèi)存必須直接管理,而分配在棧上用于保存變量的內(nèi)存則會在其棧幀彈出時自動清理。
OC將堆內(nèi)存管理抽象出來了。不需要用malloc和free來分配或釋放對象所占內(nèi)存。OC運行期環(huán)境把這部分工作抽象為一套內(nèi)存管理架構(gòu),名叫“引用計數(shù)”
在OC代碼中有時會遇到定義不含*的變量,他們可能會使用??臻g,這些變量保存的不是OC對象 CGRect就是例子
在這里插入圖片描述
CGRect是c結(jié)構(gòu)體

struct CGRect {CGpoint origin;
    CGSize siza;
};
typedef struct CGRect CGRect;

整個系統(tǒng)框架都在使用這種結(jié)構(gòu)體,如果改用OC對象來做的話,性能會受影響,與創(chuàng)建結(jié)構(gòu)體相比,創(chuàng)建對象還需要額外開銷,例如分配釋放堆內(nèi)存等,如果只需要保存 int float double char等“非對象類型”那么通常使用CG熱潮天、這種結(jié)構(gòu)體就行

要點
  • OC為C語言添加了面向?qū)ο蟮奶匦?,是其超集。OC使用動態(tài)綁定的消息結(jié)構(gòu),在運行時才會檢查對象類型。接收一條消息之后,在接受一條消息后,應(yīng)該執(zhí)行何種代碼,由運行期環(huán)境而非編譯器來決定。
  • 理解c語言的核心概念有助于寫好OC程序,尤其要掌握內(nèi)存模型與指針
虛方法表

virtual method table 是編程語言為實現(xiàn)“動態(tài)派發(fā)”或“運行時方法綁定”而采用的一種機制。

在類頭文件中盡量少引入其他頭文件

與C和C++一樣使用頭文件與實現(xiàn)文件來區(qū)隔代碼,用OC語言編寫“類”的標準方式為:以類名做文件名,分別創(chuàng)建兩個文件,頭文件后綴用.h,實現(xiàn)文件后綴用.m,創(chuàng)建好一個類之后,其代碼看上去如下所示

//
//  EOCPerson.h
//  EOC1.1
//
//  Created by zzy on 2022/12/22.
//
#importNS_ASSUME_NONNULL_BEGIN

@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString* firstName;
@property (nonatomic, copy) NSString* lastName;

@end

NS_ASSUME_NONNULL_END

//  EOCPerson.m
//  EOC1.1
//
//  Created by zzy on 2022/12/22.
//

#import "EOCPerson.h"

@implementation EOCPerson

@end

OC語言編寫任何類基本都需要引入Foundation框架,如果不引入這個文件的話,那么就要引入與其超類所屬框架相對應(yīng)的“基本頭文件”,在創(chuàng)建iOS應(yīng)用程序時,通常會繼承UIViewController類,而這些子類的的頭文件需要引入UIKit.h
EOCPerson類其頭文件中引入了整個Foundation框架,那如果此類繼承自Foundation框架中的某個類,那么EOCPerson類的使用者可能會用到其基類的中的許多內(nèi)容。繼承自UIViewController的那些類也是如此,其使用者可能會用到UIKit中的大部分內(nèi)容。
你創(chuàng)建了一個新類EOCEmployer,然后你覺得每個EOCPerson實例都需要有一個EOCEmployer于是添加了一個屬性
@property (nonatomic, strong) EOCEmployer *employer;
但你需要引入#import "EOCEmployer.h",這種辦法可行,但是不夠優(yōu)雅,在編譯一個使用了EOCPerson類的文件時,不需要知道EOCEmployer的具體細節(jié),只需要知道有一個類名叫EOCEmployer就好,有一個辦法可以將這一情況告訴編譯器
@class EOCEmployer;
“向前聲明”,現(xiàn)在EOCPerson的頭文件就是這樣

//  EOCPerson.h
//  EOC1.1
//
//  Created by zzy on 2022/12/22.
//

#import@class EOCEmployer;

@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString* firstName;
@property (nonatomic, copy) NSString* lastName;
@property (nonatomic, strong) EOCEmployer *employer;
@end

EOCPerson類的實現(xiàn)文件則需要引入EOCEmployer類的頭文件,因為若要使用后者,則需要知道所有接口細節(jié),實現(xiàn)文件就需要引入#import "EOCEmployer.h",將引入頭文件的時機盡量延后,只有在確有需要時才引入,以減少類的使用者所引入的頭文件數(shù)量,假設(shè)本例把EOCEmployer.h引入到EOCPerson.h,那么只需要引入EOCPerson.h就可以一并引入EOCEmployer的所有內(nèi)容了,但這樣需要引入許多根本用不到的內(nèi)容,增加了不必要的編譯時間。

  • 向前聲明也解決了兩個類互相引用的問題。如果在各自的頭文件引用了對方的頭文件,會導致循環(huán)引用,當解析其中的一個頭文件時編譯器會發(fā)現(xiàn)它引入了另一個頭文件,而那個頭文件又回過頭來引用第一個頭文件,雖然使用import而非include雖然不會導致死循環(huán),但這意味著兩個類里面有一個無法被正確編譯。
    有時候必須要在頭文件中引入其他頭文件。如果你寫的類繼承自某個超類,則必須引入定義那個超類的頭文件。
    同理,若要聲明你寫的類遵從某個協(xié)議,那么該協(xié)議必須擁有完整定義,且不能使用向前聲明,向前聲明只能告訴編譯器有這個協(xié)議,而此時編譯器是需要知道該協(xié)議中定義的方法。
    若要因為實現(xiàn)屬性,實例變量或者要遵循協(xié)議而必須引入頭文件,則應(yīng)盡量將其移至“class—continuation”分類中,這樣做不僅可以縮短編譯時間,而且還能降低彼此的依賴程度,若是依賴關(guān)系太過復雜,則會給維護帶來麻煩,而且,如果只是想把代碼的某個部分開放為公共API的話,太復雜的依賴關(guān)系也會出問題
要點
  • 除非有必要,否則不要引入頭文件,一般來說,應(yīng)該在某個類的頭文件中使用向前聲明來提及別的類,并在實現(xiàn)文件中英茹那些類的頭文件,這樣做可以盡量降低類之間的耦合
  • 有時無法使用向前聲明,比如要聲明某個類遵循一項協(xié)議。這種情況下,盡量把該類遵循某協(xié)議的這條聲明移動至“class-continuation分類中”如果不行的話,就把協(xié)議單獨放在一個頭文件中,然后將其引入。
多用字面量語法,少用與之等價的方法

在使用oc時要經(jīng)常用到Foundation框架,經(jīng)常用到NSString,NSNumber,NSArray,NSDictionary。從類名上即可看出各自所表示的數(shù)據(jù)結(jié)構(gòu)。
有一種方式能非常簡單的方式能創(chuàng)建NSString對象:“字符串字面量”,NSString *someString = @"EOC2.0";如果不用這種語法的話就要用常見的alloc init方法來分配并初始化NSString對象了,這種方法可以縮減源代碼長度,使其更為易讀。

字面量數(shù)值

能夠以NSNumber實例表示的所有 數(shù)據(jù)類型都可以使用該語法。

NSString *someString = @"EOC2.0";
    NSNumber *intNumber = @1;
    NSNumber *floatNumber = @2.5f;
    NSNumber *doubleNumber = @3.14159;
    NSNumber *boolNumber = @YES;
    NSNumber *charNumber = @'a';
    //字面量語法也適用于以下表達式;
    int x = 5;
    float y = 6.32f;
    NSNumber *expressionNumber = @(x * y);
字面量數(shù)組

數(shù)組是常用的數(shù)據(jù)結(jié)構(gòu),非字面量語法創(chuàng)建實例:

NSArray *season = [NSString arrayWithOjbects:@"spring",@"summer",@"autumn",@"winter",nil];

使用字面量語法:

NSArray *season = @[@"spring",@"summer",@"autumn",@"winter"];

這種做法不僅簡單,而且利于操作數(shù)組。數(shù)組常見操作就是取某個下標所對應(yīng)的對象,如果不用字面量操作:

NSString *sum = [season objectAtIndex:1];

使用字面量:

NSString *sum = season[1];

要注意,若數(shù)組元素對象中有nil,則會拋出異常,字面量語法實際上只是一種語法糖,其效果等于是先創(chuàng)建了一個數(shù)組,然后把方括號內(nèi)的所有對象都添加進數(shù)組,如果發(fā)現(xiàn)nil則會停止添加(arrayWithObjects:方法會依次處理各個參數(shù),直到發(fā)現(xiàn)nil為止)
使用字面量語法會更為安全,出現(xiàn)異常會令程序終止執(zhí)行,這比創(chuàng)建好數(shù)組之后才發(fā)現(xiàn)元素個數(shù)少了要好。

字面量字典

Dictionary ,映射型數(shù)據(jù)結(jié)構(gòu),鍵值對

NSDictionary *personData = [NSDictionarydictionaryWithObjectsAndKeys:

                @"Matt", @"firstName", 

                @"Galloway", @"lastName", 

                [NSNumber numberWithInt:28], @"age",   

                 nil];

順序是 《對象》,《鍵》 與

通常理解為 把“鍵”映射到“對象”,相反

字面量:

NSDictionary *personData = @{@"firstName" : @"Matt",

                       @"lastName" : @"Galloway",

                     @"age" : @28};

28區(qū)別原因:字典中的對象和鍵必須都是Objective-C對象,所以不能把28直接放進去,而要封裝在NSNumber實例中才行

由鍵訪問其值 : 不用字面量: NSString *lastNamge = [personData objectForKey:@“l(fā)astName”];

使用字面量:NSString *lastName = personData[@“l(fā)astName”];

可變數(shù)組與字典:

修改可變數(shù)組與字典內(nèi)容的標準做法是:

[mutableArray replaceObjectAtIndex:1 withObject:@"dog"];

[mutableDictionary setObject:@"Galloway"forKey:@"lastName"];

換成去下標:

mutableArray[1] = @"dog";

  mutableDictionary[@"lastName"] = @"Galloway";
局限性:

除了字符串以外,所創(chuàng)建出來的對象必須屬于Foundation框架。

使用字面量語法創(chuàng)建出來的字符串、數(shù)組、字典對象都是不可變的(immutable)

想要可變版本的對象,需復制一份:NSMutableArray *mutable = [@[@1, @2, @3]mutableCopy];

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁題目:iOS—EffectiveObjective—C2.0(1)-創(chuàng)新互聯(lián)
網(wǎng)站路徑:http://weahome.cn/article/docjph.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部