日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS - OC 面向对象语法

發(fā)布時間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS - OC 面向对象语法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、類

  • 1)根類:因為類 NSObject 是層次結(jié)構(gòu)的最頂層,因此稱為根類。

    • 可以將類稱為子類(subclass)和父類(superclass),也可以將類稱為子類和超類。
  • 2)分類/類別(category):允許以模塊的方式向現(xiàn)有類定義添加新的方法(默認(rèn)不能添加實例變量)。擴展自己或他人以前實現(xiàn)的類,使它適合自己的需要。

    • 分類的名稱括在類名之后的一對圓括號“( )”中。

      @interface QCStudent (Print)@end@implementation QCStudent (Print)@end
    • 分類文件名使用符號“+”來分隔類和分類的名字(Xcode 會自動生成)。

      QCStudent+Print.mQCStudent+Print.h
    • 分類用它可以將類的定義模塊化到相關(guān)方法的組或分類中。它還提供了擴展現(xiàn)有類定義的簡便方式,并且不必訪問類的源代碼,也無需創(chuàng)建子類。

    • 分類可以覆寫該類中的另一個方法,但是通常認(rèn)為這種做法是拙劣的設(shè)計習(xí)慣。一個類可以擁有多個分類。使用分類添加新方法來擴展類不僅會影響這個類,同時也會影響它的所有子類。分類為現(xiàn)有類添加新方法可能對你有用,但它們可能和該類的原始設(shè)計或意圖不一致。對象/分類命名對必須是唯一的。

    • iOS 開發(fā)中,分類默認(rèn)不允許添加屬性。但是如果在自己開發(fā)的框架中,希望在分類中動態(tài)添加屬性,可以通過 OC 運行時的關(guān)聯(lián)對象功能添加,詳見 iOS - OC Category 分類。

  • 3)類的擴展:有一種特殊的情況是創(chuàng)建一個未命名的分類,并且括號“( )”之間不指定名字。

    • 這種特殊的語法定義稱為類的擴展。定義一個像這樣的未命名的分類時,可以通過定義額外的實例變量和屬性來擴展類,這在有命名的分類中是不允許的。

      @interface QCStudent ()@end@implementation QCStudent@end
    • 未命名的分類中聲明的方法需要在主實現(xiàn)區(qū)域?qū)崿F(xiàn),而不是在分類的的實現(xiàn)區(qū)域。

    • 未命名的分類的方法都是私有的。如果需要寫一個類,而且數(shù)據(jù)和方法僅供這個類本身使用,未命名分類比較合適。

  • 4)抽象類:有時創(chuàng)建類只是為了更容易創(chuàng)建子類。因此,這些類名為抽象類,或等價的稱為抽象超類。在該類中定義方法和實例變量,但不希望任何人從這個類創(chuàng)建實例。

  • 5)類與類之間的關(guān)系:

    • 類的包含(復(fù)合):
      • 一個類中有另一個類的 @class 聲明。一個類中包含有 #import 另一個類的 .h 頭文件。
      • 一般在 .h 頭文件中用 @class 聲明一個類,在 .m 文件中使用到該類時再在 .m 文件中包含該類的 .h 頭文件。
      #import:文件包含。這種方式會包含被引用類的所有信息,包括被引用類的變量和方法;@class :類的聲明。這種方式只是告訴編譯器另一個類的聲明,具體這個類里邊有什么信息,這里不需要知道,等實現(xiàn)文件中具體用到時,才會真正的去查看引用類的信息,因為編譯器不需要引入和處理整個文件,只需知道是一個類名,在 .h 文件中使用 @class 指令提高了效率。
  • 6)類的加載:

    • 1>、類加載時自動調(diào)用方法:+ (void)load;

      + (void)load {NSLog(@"%@",@"Student ------------- load");}
    • 2>、類首次使用時自動調(diào)用方法:+ (void)initialize;

      + (void)initialize {NSLog(@"%@",@"Student ------------- initialize");}
    • 3>、使用 %@ 打印對象時會自動調(diào)用方法:- (NSString *)description;

      // description 覆寫- (NSString *)description {return [NSString stringWithFormat:@"age : %d, name : %@", self.age, self.name];}
  • 7)是在子類中使用的實例變量,必須先在接口部分聲明,而不是在實現(xiàn)部分聲明。在實現(xiàn)部分聲明和合成的實例變量是私有的,子類中不能直接訪問,需要明確定義或合成取值方法,才能訪問實例變量的值。

  • 8)類前綴:

    • 使用 Objective-C 開發(fā) iOS 程序時,最好在每個類名前面加一個前綴,用來標(biāo)識這個類。

    • 目的是防止 N 個人開發(fā)了一樣的類,出現(xiàn)沖突。
      • 比如 Jake Will、Kate Room 在同一個項目中都各自開發(fā)了個 Button 類,這樣的程序是不能運行起來的。
      • 解決方案:Jake Will 的類名叫做 JWButton,Kate Room 的類名叫做 KRButton。
    • 類前綴的設(shè)置

      • Xcode 6 之前:

        • 在創(chuàng)建項目時設(shè)置。

      • Xcode 6 之后:

        • 創(chuàng)建完項目后設(shè)置。

      • 設(shè)置完后,再創(chuàng)建新的文件時會自動添加上設(shè)置的類前綴。

2、對象、方法

  • 1)類的獨特存在就是一個實例(對象),對實例執(zhí)行的操作稱為方法。

  • 2)合成對象:可以定義一個類包含其它類的一個或多個對象,這個新類的對象就是所謂的合成對象,因為它是由其它對象組成的。

    • 作為創(chuàng)建子類的代替方法,可以定義一個新類,它包含要擴展類的實例變量。然后,只需在新類中定義適合該類的方法。
  • 3)實例初始化

    • 1>、初始化方式:

      alloc :方法保證對象的所有實例變量都變成初始狀態(tài)。 創(chuàng)建對象。init :方法用于初始化類的實例變量。 初始化對象。new :可以將 alloc 和 init 的結(jié)合起來。 創(chuàng)建并初始化對象。
      • 但用兩步來實現(xiàn)創(chuàng)建和初始化的方式通常更好,這樣可以在概念上理解正在發(fā)生兩個不同的事件:首先創(chuàng)建一個對象,然后對它初始化。
    • 2>、構(gòu)造方法:實例初始化常見的編程習(xí)慣是類中所有初始化方法都以 init 開頭。如果希望在類對象初始化時做一些事情,可以通過重載 init 方法達到這個目的。下面是重載 init 方法的一個標(biāo)準(zhǔn)模板。

      不帶參數(shù):- (instancetype)init {self = [super init];if (self) {// 初始化代碼}return self; }帶參數(shù):- (instancetype)initWithAge:(int)age andNo:(int)no { self = [super init];if (self) {_age = age;_no = no; }return self;}類方法:+ (instancetype *)studentWithAge:(int)age {Student *stu = [[Student alloc] init];stu.age = age;return stu;}
      • 執(zhí)行父類的初始化方法,使得繼承的實例變量能夠正常的初始化。如果父類初始化成功,返回的值將是非空的。self 用來指明對象是當(dāng)前方法的接收者。必須將父類 init 方法的執(zhí)行結(jié)果賦值給 self,因為初始化過程改變了對象在內(nèi)存中的位置(意味著引用將要改變)。

      • 特殊類型 instancetype 表明從 init 方法返回的類型與它的初始化類(也就是初始化消息的接收者)相同。 init 被定義為返回 instancetype 類型,這是編寫可能被繼承的類 init 方法的一般規(guī)則。當(dāng)編譯器遇見 instancetype 作為返回類型,它就知道返回的類型是發(fā)送消息的對象。

  • 4)消息:請求一個類或?qū)嵗齺韴?zhí)行某個操作時,就是在向它發(fā)送一條消息,消息的接受者稱為接收者。

    • OC 采用特定的語法對類和實例應(yīng)用方法:[類/實例 方法];
  • 5)類方法(靜態(tài)方法):是對類本身執(zhí)行某些操作的方法。
    • 實例方法(動態(tài)方法):對類的實例執(zhí)行一些操作。

    • 創(chuàng)建方法名時,參數(shù)名實際上是可選的,參數(shù)名可以省略。如:- (int)set :(int)name :(int)age;

    • 方法(函數(shù))不返回任何值時,無需在方法的末尾執(zhí)行一條 return 語句。或者也可以執(zhí)行一條不帶任何指定值的 return 語句:return;。

  • 6)重寫(覆蓋):在子類中新建一個與父類中的方法同名的方法。子類中的新方法必須具有相同的返回類型,并且參數(shù)的數(shù)目和覆寫的方法相同。

    • 如果需要來擴展繼承的方法。子類中包含對 if (self = [super init]) 的判斷。
  • 7)重載:在類中,相同名字不同參數(shù)的方法的寫法有一個專門的術(shù)語來描述,叫做重載。

  • 8)懶加載

    • 對象在用到時再去加載,而且只加載一次。加載的數(shù)據(jù)比較大時可以節(jié)省內(nèi)存。
    • 一般重寫 getter 方法實現(xiàn)對象的懶加載。

      @property (strong, nonatomic) NSArray *shops;- (NSArray *)shops {// 加載數(shù)據(jù)if (_shops == nil) {NSString *filePath = [[NSBundle mainBundle] pathForResource:@"shops" ofType:@"plist"];_shops = [NSArray arrayWithContentsOfFile: filePath];}return _shops;}

3、數(shù)據(jù)封裝(實例變量)

  • 1)數(shù)據(jù)封裝:將實例變量隱藏起來的這種做法實際上涉及一個關(guān)鍵概念 --“數(shù)據(jù)封裝”。

    • 不能在類的外部編寫方法直接設(shè)置或獲取實例變量的值,而需要編寫設(shè)置方法和取值方法來設(shè)置和獲取實例變量的值,這便是數(shù)據(jù)封裝的原則。
    • 必須通過使用一些方法來訪問這些通常對“外界”隱藏的數(shù)據(jù),這種做法集中了訪問實例變量的方式,并且能夠阻止其它一些代碼直接改變實例變量的值。如果可以直接改變,會讓程序很難跟蹤、調(diào)試和修改。
  • 2)實例變量的定義作用域

    @public 全局都可以訪問,實例對象可以使用符號 “->” 直接訪問實例變量。 @protected 只能在類內(nèi)部和子類中訪問 (訪問器方法 默認(rèn)) 。@private 只能在類內(nèi)部訪問 (合成取值方法 默認(rèn))。@package 常用于框架類的實例變量,同一包內(nèi)能用,跨包就不能訪問。
  • 3)訪問器方法(accessor):取值方法和設(shè)值方法通常稱為訪問器方法。通常實例變量聲明時以下畫線( _ )字符開頭,此實例變量默認(rèn)為保護(@protected)的。在類內(nèi)部和子類中都可以訪問。

    • 設(shè)值方法(setter):設(shè)置實例變量值的方法通常總稱為設(shè)值方法。定義時在實例變量名前加上 set。如:

      // ARC- (void)setAge:(NSNumber *)age {_age = age;}// MRC- (void)setAge:(NSNumber *)age {if (_age) { [_age release]; } _age = [age retain];}
    • 取值方法(getter):用于檢索實例變量值的方法叫做取值方法。定義時直接使用實例變量名。如:

      - (NSNumber *)age {return _age;}
  • 4)合成取值方法:通常實例變量聲明時不以下畫線( _ )字符開頭,以字母開頭,并且此實例變量是私有(@private)的。只能在類內(nèi)部訪問。

    • 在接口部分中使用 @property 指令標(biāo)識屬性,聲明實例變量的 setter 和 getter 方法。 - 如:@property int numerator, denominator;

    • 在實現(xiàn)部分中使用 @synthesize 指令標(biāo)識屬性,實現(xiàn)實例變量的 setter 和 getter 方法。 - 如:@synthesize numerator, denominator;

    • 1>、如果使用了 @property 指令,就不需要在實現(xiàn)部分聲明相應(yīng)的實例變量。當(dāng)然也可以再聲明相應(yīng)的實例變量,但是那不是必須要做的,編譯器會有一些提示。

      • 可以不使用 @synthesize 指令,使用 @property 指令就足夠了,編譯器會自動為你生成 setter 和 getter 方法(聲明并實現(xiàn)),但是注意如果你不使用 @synthesize ,那么編譯器聲明的實例變量會以下劃線( _ )字符作為其名稱的第一個字符。
    • 2>、@property 的修飾

      • 在不寫任何修飾時,Xcode 會自動生成標(biāo)準(zhǔn)的 setter 和 getter 方法,寫修飾時 Xcode 會自動生成帶內(nèi)存管理的 setter 方法,標(biāo)準(zhǔn) getter 方法。

      • 參數(shù)分類:

        讀寫屬性:readwrite/readonlysetter 處理:assign/retain/copy原子性:atomic/nonatomic方法名:setter = method / getter = method引用型:strong/weak可選性:nonnull/nullable/null_unspecified/null_resettable // Xcode 7 新增特性readwrite:可讀寫,生成 setter 和 getter 方法。默認(rèn)。readonly :只讀,只生成 getter 方法。assign :修飾普通類型,在 setter 方法中直接賦值。默認(rèn)。簡單賦值,不更改引用計數(shù)。如:@property (nonatomic, assign)int age;retain :修飾 OC 對象,在 setter 方法中 release 舊值,retain 新值。釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的引用計數(shù)為 1。如:@property (nonatomic, retain)Dog *dog;copy :修飾 NSString 類型,在 setter 方法中 release 舊值,copy 新值。建立了一個相同的對象,地址不同(retain:指針拷貝 copy:內(nèi)容拷貝)。如:@property (nonatomic, copy)NSString *name;atomic :原子性,默認(rèn)。是 OC 使用的一種線程保護技術(shù),防止在寫入未完成的時候被另外一個線程讀取,造成數(shù)據(jù)錯誤。給 setter 和 getter 方法加鎖,保證多線程安全。nonatomic:非原子性,禁止多線程,變量保護,提高性能。不給 setter 和 getter 方法加鎖,執(zhí)行相對快點。setter = method:指定 setter 方法的方法名。 如:@property (nonatomic, setter = setIsRich)BOOL rich; 將 rich 的 setter 方法重命名為 setIsRich 。getter = method:指定 getter 方法的方法名。 如:@property (nonatomic, getter = isRich)BOOL rich; 將 rich 的 getter 方法重命名為 isRich 。strong :強引用,在 OC 中對象默認(rèn)都是 strong。(ARC 下的)和(MRC)retain 一樣 (默認(rèn))。viewController 對根視圖是強引用,view addSubviews 方法是向數(shù)組中添加子視圖,數(shù)組會對子視圖強引用。weak :弱引用,weak 的作用,一旦沒有強引用,會被立即釋放。(ARC 下的)和(MRC)assign 一樣。蘋果從 StoryBoard 拖線默認(rèn)是 weak。weak 當(dāng)指向的內(nèi)存釋放掉后自動 nil 化,防止野指針。nonnull :不可為空nullable :可以為空null_unspecified:不確定是否可以為空(極少情況)null_resettable :set 方法可以為 nil,get 方法不可返回 nil,只能用在屬性的聲明中。
  • 5)點運算符(點語法):訪問的是方法(setter/getter 方法),不是實例變量。

    • 合成取值方法中可以使用點運算符訪問屬性,也可以對自定義的方法使用點運算符,如語句 myFraction.print ,并未考慮編碼風(fēng)格是否良好。

    • 點運算符通常用在屬性上,用于設(shè)置或取得實例變量的值。做其它工作的方法通常不是由點運算符執(zhí)行的,而是使用傳統(tǒng)的方括號形式的消息表達式作為首選的語法。

  • 6)尖運算符(->):當(dāng)實例變量定義為 @public 類型時,實例對象可以使用符號 “->” 直接訪問實例變量。 如:car -> _speed = 80; int a = car -> _speed;

  • 7)局部變量:是基本的 C 數(shù)據(jù)類型,并沒有默認(rèn)的初始值,所以在使用前要先賦值。
    • 局部對象變量:默認(rèn)初始值為 nil 。

      • 方法的參數(shù)名也是局部變量。執(zhí)行方法時,通過方法傳遞的任何參數(shù)都被復(fù)制到局部變量中。因為方法使用參數(shù)的副本,所以不能改變通過方法傳遞的原值。
      • 如果參數(shù)是對象,可以更改其中的實例變量值。當(dāng)你傳遞一個對象作為參數(shù)時,實際上是傳遞了一個數(shù)據(jù)存儲位置的引用。
    • 靜態(tài)變量:在局部變量聲明前加上關(guān)鍵字 static ,可以使局部變量保留多次調(diào)用一個方法所得的值。靜態(tài)變量的初始值為 0 。

      • 很多情況下想要將變量定義為全局變量,但不是外部變量,可以在包含這個特定類型實現(xiàn)的文件中將這個變量定義為 static 。
    • 外部變量:在方法外定義的變量不僅是全局變量,而且是外部變量。

      • 使用外部變量時,必須遵循下面這條重要原則:變量必須定義在源文件中的某個位置。即在所有的方法和函數(shù)之外定義變量,并且前面不加關(guān)鍵字 extern 。在所有的函數(shù)之外聲明變量,在聲明前面加上關(guān)鍵字 extern 。

      • 處理外部變量時,變量可以在許多地方聲明為 extern ,但是只能定義一次。

4、繼承、多態(tài)

  • 1)繼承的概念作用于整個繼承鏈。

    • 類的每個實例(對象)都擁有自己的實例變量,即使這些實例變量是繼承來的。

    • 繼承通常用于擴展一個類。不能通過繼承刪除或減少方法。

    • 為什么需要創(chuàng)建子類:(1)希望繼承一個類的函數(shù),也需加入一些新的方法和/或?qū)嵗兞俊?#xff08;2)希望創(chuàng)建一個類的特別版本。(3)希望通過覆寫一個或多個方法 來改變類的默認(rèn)行為。

  • 2)多態(tài):使不同的類共享相同方法名稱的能力稱為多態(tài)。能夠使來自不同類的對象定義相同名稱的方法。

  • 3)動態(tài)類型:id 類型的對象。在運行時而不是編譯時確定對象所屬的類,能使程序直到執(zhí)行時才確定對象所屬的類。
    • 靜態(tài)類型:將一個變量定義為特定類的對象時,使用的是靜態(tài)類型。靜態(tài)指的是對存儲在變量中的對象類型進行顯示的聲明。
    • 動態(tài)綁定:在運行時而不是編譯時確定對象需要調(diào)用的方法,能使程序直到執(zhí)行時才確定實際要調(diào)用的對象方法。

      • OC 系統(tǒng)總是跟蹤對象所屬的類。
      • id 類型的對象先判定對象所屬的類(動態(tài)類型),然后在運行時確定需要動態(tài)調(diào)用的方法,而不是在編譯的時候(動態(tài)綁定)。

      • 為什么還要關(guān)心靜態(tài)類型:(1)它能更好的在程序編譯階段而不是運行時指出錯誤。(2)它能提高程序的可讀性。

      • 如果使用動態(tài)類型來調(diào)用一個方法,需要注意一下規(guī)則:如果在多個類中實現(xiàn)名稱相同的方法,那么每個方法都必須符合各個參數(shù)的類型和返回值類型,這樣編譯器才能為消息表達式生成正確的代碼。

    • 處理動態(tài)類型的方法:

      • 以下總結(jié)了 NSObject 類所支持的一些基本方法,其中,class-object 是一個類對象(通常是由 class 方法產(chǎn)生的),selector 是一個 SEL 類型的值(通常是由 @selector 指令產(chǎn)生的)。

        - (BOOL)isKindOfClass:class-object // 對象是不是 class-object 或其子類的成員- (BOOL)isMemberOfClass:class-object // 對象是不是 class-object 的成員+ (BOOL)isSubclassOfClass:class-object // 某個類是否是指定類的子類- (BOOL)respondsToSelector:selector // 對象是否能夠響應(yīng) selector 所指定的方法+ (BOOL)instancesRespondToSelector:selector // 指定的類實例是否能響應(yīng) selector- (id)performSelector:selector // 應(yīng)用 selector 指定的方法- (id)performSelector:selector withObject:object // 應(yīng)用 selector 指定的方法,傳遞參數(shù) object- (id)performSelector:selector withObject:object1 withObject:object2 // 應(yīng)用 selector 指定的方法,傳遞參數(shù) object1 和 object2[Square class] // 從名為 Square 的類中獲得類對象[mySquare class] // 知道對象 mySquare 所屬的類@selector(alloc) // 為名為 alloc 的方法生成一個 SEL 類型的值。
  • 4)消除 performSelector: 方法警告

    #pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks"// performSelector: 方法#pragma clang diagnostic pop

5、協(xié)議、代理

  • 1)協(xié)議:是多個類共享的一個方法列表。協(xié)議中列出的方法沒有相應(yīng)的實現(xiàn),計劃由其他人來實現(xiàn)。協(xié)議中列出的方法,有些是可以選擇實現(xiàn),有些是必須實現(xiàn)。

    • 1>、如果你定義了自己的協(xié)議,那么不必由自己實現(xiàn)它。但是,這就告訴其他程序員,如果要采用這項協(xié)議,則必須實現(xiàn)這些方法。這些方法可以從超類繼承。

      • 協(xié)議不引用任何類,它是無類的。

      • 分類也可以采用一項協(xié)議。

    • 2>、定義一個協(xié)議很簡單:只要使用 @protocol 指令,后面跟上你給出的協(xié)議名稱。定義一項協(xié)議時,可以擴展現(xiàn)有協(xié)議的定義。

      @protocol PlayerDelegate <NSObject>- (void)end;@end
    • 3>、協(xié)議的修飾

      @optional:該指令之后列出的所有方法都是可選的。@required:該指令之后列出的所有方都是必須實現(xiàn)的,默認(rèn)。由于 OC 是弱語法,雖然字面上是必須,但編譯器并沒有強求實現(xiàn)。
    • 4>、協(xié)議的聲明

      @protocol protocol-name
    • 5>、協(xié)議的檢查

      // 檢查一個對象是否遵守某項協(xié)議。- (BOOL)conformsToProtocol:(Protocol *)aProtocol;// 用于獲取一個協(xié)議名稱,并產(chǎn)生一個 Protocol 對象,conformsToProtocol: 方法期望這個對象作為它的參數(shù)。@protocol(Drawing)// 檢查對象是否能夠響應(yīng) selector 所指定的方法。- (BOOL)respondsToSelector:selector// 為名為 alloc 的方法生成一個 SEL 類型的值。@selector(alloc)
  • 2)非正式協(xié)議:實際上是一個分類,列出了一組方法但并沒有實現(xiàn)它們。非正式協(xié)議通常是為根類定義的,有時,非正式協(xié)議也稱為抽象協(xié)議。

    • 聲明非正式協(xié)議的類自己并不實現(xiàn)這些方法,并且選擇實現(xiàn)這些方法的子類需要在它的接口部分重新聲明這些方法,同時還要實現(xiàn)這些方法中的一個或多個。

    • 指令 @optional 添加到 OC 2.0 語言中,用于取代非正式協(xié)議的使用。

  • 3)代理:協(xié)議也是一種兩個類之間的接口定義。定義了協(xié)議的類可以看作是將協(xié)議定義的方法代理給了實現(xiàn)它們的類。

    • 代理設(shè)計模式的作用:
      • 1、A 對象監(jiān)聽 B 對象的一些行為,A 成為 B 的代理
      • 2、B 對象想告訴 A 對象一些事情,A 成為 B 的代理
    • 代理設(shè)計模式的總結(jié):
      • 1、如果你想監(jiān)聽別人的一些行為,那么你就要成為別人的代理
      • 2、如果你想告訴別人一些事情,那么就讓別人成為你的代理
    • 代理設(shè)計模式的開發(fā)步驟:
      • 1、擬一份協(xié)議(協(xié)議名字的格式:控件名 + Delegate),在協(xié)議里面聲明一些代理方法(一般代理方法都是 @optional)
      • 2、聲明一個代理屬性:@property (nonatomic, weak) id delegate;
      • 3、在內(nèi)部發(fā)生某些行為時,調(diào)用代理對應(yīng)的代理方法,通知代理內(nèi)部發(fā)生什么事
      • 4、設(shè)置代理:xxx.delegate = yyy;
      • 5、yyy 對象遵守協(xié)議,實現(xiàn)代理方法

6、為什么 Objective-C 的方法調(diào)用要用方括

  • 為什么 Objective-C 的方法調(diào)用要用方括號 [obj foo],而不是別的語言常常使用的點 obj.foo ?

    • 首先要說的是,Objective-C 的歷史相當(dāng)久遠,如果你查 wiki 的話,你會發(fā)現(xiàn):Objective-C 和 C++ 這兩種語言的發(fā)行年份都是 1983 年。在設(shè)計之初,二者都是作為 C 語言的面向?qū)ο蟮慕影嗳?#xff0c;希望成為事實上的標(biāo)準(zhǔn)。最后結(jié)果大家都知道了,C++ 最終勝利了,而 Objective-C 在之后的幾十年中,基本上變成了蘋果自己家玩的玩具。不過最終,由于 iPhone 的出現(xiàn),Objective-C 迎來了第二春,在 TOBIE 語言排行榜上,從 20 名開外一路上升,排名曾經(jīng)超越過 C++,達到了第三名(下圖),但是隨著 Swift 的出現(xiàn),Objective-C 的排名則一路下滑。

    • Objective-C 在設(shè)計之初參考了不少 Smalltalk 的設(shè)計,而消息發(fā)送則是向 Smalltalk 學(xué)來的。Objective-C 當(dāng)時采用了方括號的形式來表示發(fā)送消息,為什么沒有選擇用點呢?我個人覺得是,當(dāng)時市面上并沒有別的面向?qū)ο笳Z言的設(shè)計參考,而 Objective-C 「發(fā)明」了方括號的形式來給對象發(fā)消息,而 C++ 則「發(fā)明」了用點的方式來 “發(fā)消息”。有人可能會爭論說 C++ 的「點」并不是真正的發(fā)消息,但是其實二者都是表示「調(diào)用對象所屬的成員函數(shù)」。

    • 另外,有讀者評論說使用方括號的形式是為了向下兼容 C 語言,我并不覺得中括號是唯一選擇,C++ 不也兼容了 C 語言么?Swift 不也可以調(diào)用 C 函數(shù)么?

    • 最終,其實是 C++ 的「發(fā)明」顯得更舒服一些,所以后來的各種語言都借鑒了 C++ 的這種設(shè)計,也包括 Objective-C 在內(nèi)。Objective-C 2.0 版本中,引入了 dot syntax,即:

      a = obj.foo 等價于 a = [obj foo]obj.foo = 1 則等價于 [obj setFoo:1]
    • Objective-C 其實在設(shè)計之中確實是比較特立獨行的,除了方括號的函數(shù)調(diào)用方式外,還包括比較長的,可讀性很強的函數(shù)命名風(fēng)格。

    • 我個人并不討厭 Objective-C 的這種設(shè)計,但是從 Swift 語言的設(shè)計來看,蘋果也開始放棄一些 Objective-C 的特點了,比如就去掉了方括號這種函數(shù)調(diào)用方式。

    • 所以,回到我們的問題,我個人認(rèn)為,答案就是:Objective-C 在 1983 年設(shè)計的時候,并沒有什么有效的效仿對象,于是就發(fā)明了一種有特點的函數(shù)調(diào)用方式,現(xiàn)在看起來,這種方式比點操作符還是略遜一籌。

    • 大多數(shù)語言一旦被設(shè)計好,就很難被再次修改,應(yīng)該說 Objective-C 發(fā)明在 30 年前,還是非常優(yōu)秀的,它的面向?qū)ο蠡O(shè)計得非常純粹,比 C++ 要全面得多,也比 C++ 要簡單得多。

轉(zhuǎn)載于:https://www.cnblogs.com/QianChia/p/5780671.html

總結(jié)

以上是生活随笔為你收集整理的iOS - OC 面向对象语法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩成人一区二区在线观看 | 亚洲最新av| 青青草综合网 | 日欧一级片 | 九九精品在线观看 | 久久国产精品免费观看 | 国产日本亚洲 | 亚洲午夜精品久久久 | 榴莲视频黄色 | 亚洲视频在线播放免费 | 在线观看精品视频 | 影音先锋丝袜美腿 | 久久人人爽人人爽人人片 | 天天做天天操 | 日韩视频 中文字幕 | 日韩中文字幕一区二区三区四区 | 亚洲自拍小视频 | 国产一区二区三区在线视频 | 国产福利短视频 | 久久国产主播 | 少妇毛片视频 | 欧美男优| 特大黑人巨交吊性xx | 在线成年人视频 | 潘金莲一级淫片aaaaaaa | 亚洲男人的天堂在线 | 51 吃瓜网| 人妻少妇无码精品视频区 | 欧美成人一二三区 | 三级黄色免费 | 欧美成人区 | www亚洲色图| 美女免费福利视频 | 美国一区二区三区 | 成年激情网 | 久久久久久久久久久久国产精品 | 1000部啪啪 | 色综合视频在线 | 欧美日韩一区精品 | 青青草操| 久久成人免费电影 | 最新av在线网站 | 天堂аⅴ在线最新版在线 | 男人视频网站 | 男人天堂手机在线观看 | 青青草原国产在线 | 99riav国产在线观看 | 91av在线网站 | 99一区二区 | 欧美第二区| 严厉高冷老师动漫播放 | 91一起草 | 亚洲精品一区在线 | 亚洲四区 | 亚洲乱码中文字幕久久孕妇黑人 | 日韩精品一区三区 | 九九久久免费视频 | 欧美精品亚洲精品 | 国产精品调教 | 91叉叉叉 | 亚欧洲精品在线视频免费观看 | 国产综合在线观看视频 | 性欧美日本 | 国产麻豆午夜三级精品 | 无码人妻少妇伦在线电影 | 欧美黑大粗 | 欧美成人专区 | 日韩中文娱乐网 | 波多野一区二区 | 成人免费国产 | 午夜视频在线观看网站 | 欧美一级黄色片在线观看 | 欧美成人视屏 | 国产97在线 | 亚洲 | 一区二区中文字幕 | 国产综合在线观看 | 亚洲精选一区 | 亚洲国产精品国自产拍久久 | 久久精品首页 | 成人午夜精品无码区 | www.av天天 | 亚洲码国产精品高潮在线 | 9i在线看片成人免费 | 中文字幕 自拍 | 亚洲精品免费电影 | 佐山爱av在线 | 狠狠天堂| 日韩精品一区二区亚洲av观看 | 亚洲欧洲一区二区在线观看 | 理论片高清免费理伦片 | 一本久道久久 | 婷婷伊人综合中文字幕 | 亚洲爱色| 欧美一区二区三区免费在线观看 | 波多野吉衣在线视频 | 另类欧美尿交 | 永久视频 | 好看的中文字幕电影 | 日本色片网站 |