【Objective-C】07-自定義構造方法和description方法

来源:http://www.cnblogs.com/AnnieBabygn/archive/2016/04/22/5420073.html
-Advertisement-
Play Games

在第5講中已經介紹瞭如何定義類和創建並初始化對象,比如有Student這個類1.Student.h 1 #import <Foundation/Foundation.h> 2 3 @interface Student : NSObject { 4 int _age; 5 } 6 - (void)se ...


第5講中已經介紹瞭如何定義類和創建並初始化對象,比如有Student這個類

1.Student.h

  1. 1 #import <Foundation/Foundation.h>
  2. 3 @interface Student : NSObject {
  3. 4 int _age;
  4. 5 }
  5. 6 - (void)setAge:(int)age;
  6. 7 - (int)age;
  7. 8 @end
複製代碼


2.Student.m

  1. 1 #import "Student.h"
  2. 3 @implementation Student
  3. 4 - (void)setAge:(int)age {
  4. 5 _age = age;
  5. 6 }
  6. 7 - (int)age {
  7. 8 return _age;
  8. 9 }
  9. 10 @end
複製代碼


3.在main函數中創建一個Student對象

  1. 1 #import "Student.h"
  2. 3 int main(int argc, const char * argv[])
  3. 4 {
  4. 6 @autoreleasepool {
  5. 7 Student *stu = [[Student alloc] init];
  6. 9 stu.age = 10;
  7. 10 
  8. 11 [stu release];
  9. 12 }
  10. 13 return 0;
  11. 14 }
複製代碼


* 在第7行調用Student的alloc方法分配記憶體,然後再調用init方法初始化對象

* 像init這樣用來初始化對象的方法,我們可以稱為"構造方法"

一、自定義構造方法

預設的構造方法,也就是init方法,它是不接收任何參數的。因此,在實際開發中,為了方便,會經常自定義構造方法。

接下來,自定義一個構造方法,可以傳入一個age參數來初始化Student對象

1.在Student.h中添加方法聲明

- (id)initWithAge: (int)age;

* 構造方法的方法名一般都會以init開頭,返回值跟init方法一樣為id類型,id可以代表任何OC對象

* 這個構造方法接收一個int類型的age參數,目的是在初始化Student對象時,順便設置成員變數_age的值

2.在Student.m中實現構造方法


  1. 1 - (id)initWithAge:(int)age {
  2. 2 self = [super init];
  3. 3 if (self != nil) {
  4. 4 _age = age;
  5. 5 }
  6. 6 return self;
  7. 7 }
複製代碼


* 跟Java一樣,構造方法內部首先要調用父類的構造方法,在第2行調用了父類的init方法,它會返回初始化好的Student對象,這裡把返回值賦值給了self,self代表Student對象本身

* 第3~5行的意思是:如果self不為nil,也就是初始化成功,就給成員變數_age進行賦值

* 最後返回初始化過後的self,整個構造方法就結束了

3.簡化構造方法

由於C語言和OC的語法特性,我們可以對構造方法進行簡化,先簡化第3行

  1. 1 - (id)initWithAge:(int)age {
  2. 2 self = [super init];
  3. 3 if (self) {
  4. 4 _age = age;
  5. 5 }
  6. 6 return self;
  7. 7 }
複製代碼


* 第3行的 if(self) 跟 if(self!=nil) 是等價的

* 還可以將第2、3行合併,繼續簡化

  1. 1 - (id)initWithAge:(int)age {
  2. 2 if ( self = [super init] ) {
  3. 3 _age = age;
  4. 4 }
  5. 5 return self;
  6. 6 }
複製代碼


* 第2行的總體意思是:先調用父類的構造方法init,然後將返回值賦值給self,接著判斷self是否為nil

* 以後的構造方法都這樣寫了

4.調用構造方法

  1. 1 Student *stu = [[Student alloc] initWithAge:10];
  2. 3 NSLog(@"age is %i", stu.age);
  3. 5 [stu release];
複製代碼


* 在第1行調用了構造方法initWithAge:,並傳入10作為參數,因此Student對象的成員變數_age會變為10

* 在第3行列印Student的成員變數_age,列印結果:

2013-04-19 21:36:47.880 構造方法[448:303] age is 10

二、description方法1.NSLog回顧

眾所周知,我們可以用NSLog函數來輸出字元串和一些基本數據類

1 int age = 11;2 NSLog( @" age is %i", age);

* 第2行的%i代表會輸出一個整型數據,右邊的變數age會代替%i的位置進行輸出

* 輸出結果:

2013-04-19 21:43:47.674 構造方法[483:303] age is 11

2.NSLog輸出OC對象

其實,除了可以輸出基本數據類型,NSLog函數還可以輸出任何OC對象

  1. 1 Student *stu = [[Student alloc] initWithAge:10];
  2. 3 NSLog(@"%@", stu);
  3. 5 [stu release];
複製代碼

* 在第3行用NSLog函數輸出stu對象,註意左邊的格式符%@,以後想輸出OC對象,就得用%@這個格式符

* NSLog函數一旦發現用%@輸出某個OC對象時,就會調用這個對象的description方法(這個方法返回值是NSString類型,是OC中的字元串類型),並且將description方法返回的字元串代替%@的位置進行輸出

* description方法的預設實現是返回這樣的格式:<類名: 對象的記憶體地址>,因此上面代碼的輸出結果為

2013-04-19 21:46:49.896 構造方法[492:303] <Student: 0x100109910>

Student是類名,0x100109910是對象的記憶體地址

* 註意了,%@只能用於輸出OC對象,不能輸出結構體等其他類型

* 有Java開發經驗的人應該能感受到OC中的description方法就是Java中的toString方法

3.重寫description方法

description方法的預設實現是返回類名和對象的記憶體地址,這樣的話,使用NSLog輸出OC對象,意義就不是很大,因為我們並不關心對象的記憶體地址,比較關心的是對象內部的一些成變數的值。因此,會經常重寫description方法,覆蓋description方法的預設實現
比如,重寫Student的description方法,返回成員變數_age的值

  1. 1 - (NSString *)description {
  2. 2 return [NSString stringWithFormat:@"age=%i", _age];
  3. 3 }
複製代碼

* 在第2行調用了NSString這個類的靜態方法stringWithFormat初始化一個字元串對象,並返回這個字元串

* 如果你會使用NSLog的話,那就應該能理解第2行的方法參數是什麼意思了

* 假如_age是10,那麼description方法返回的字元串就是@"age=10"

* 可能有人會覺得奇怪,之前創建的Student對象是需要釋放的,為什麼這裡創建的字元串對象不用釋放?要想徹底明白這個問題,需要先瞭解OC的記憶體管理,這裡我們暫不做詳細討論,後面會有章節詳細討論記憶體管理。你可以先記住一個規則:一般情況下,靜態方法返回的對象,都不用手動釋放。

* 重寫完description方法後,再次執行下麵的代碼

  1. Student *stu = [[Student alloc] initWithAge:10];
  2. 3 NSLog(@"%@", stu);
  3. 5 [stu release];
複製代碼


1輸出結果為:

2013-04-19 22:09:56.625 構造方法[531:303] age=10

4.description方法的陷阱

千萬不要在description方法中同時使用%@和self,下麵的寫法是錯誤的:

  1. - (NSString *)description {
  2. 2 return [NSString stringWithFormat:@"%@", self];
  3. 3 }
複製代碼


1第2行同時使用了%@和self,代表要調用self的description方法,因此最終會導致程式陷入死迴圈,迴圈調用description方法

原文鏈接:http://www.cnblogs.com/mjios/archive/2013/04/19/3031412.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • //<![CDATA[ //這裡放代碼 //]]> 基本類型 引用類型 動態添加屬性 不可以,不會出錯,但會出現underfined 可以 複製變數值 相互獨立 指向同一個對象,相互影響 傳遞參數(函數外部的值傳遞給函數內部) 相互獨立 指向同一個對象,相互影響,但是在函數內部重寫的值,不會影響外部 ...
  • 1/javascript誕生/作用 javascript誕生於:1995年 當時作用:客戶端數據驗證 開發公司:Netscape 發展至今:各種交互(包括於瀏覽器),數據驗證,單頁面應用,非同步載入... 2/javascript組成 ECMAScript(核心),DOM(文檔對象模型),BOM(瀏覽 ...
  • × 目錄 [1]定義 [2]關鍵幀 [3]動畫屬性 [4]多值 [5]API 前面的話 transition過渡是通過初始和結束兩個狀態之間的平滑過渡實現簡單動畫的;而animation則是通過關鍵幀@keyframes來實現更為複雜的動畫效果。本文將介紹關於animation動畫的相關知識 定義 ...
  • <script type="text/javascript"> var refid='dasdasd,dadsad'; var reg =/^([\u0391-\uFFE5\d\w,])*([\u0391-\uFFE5\d\w]+)$/; if(refid != "") { if(reg.exec( ...
  • 之前學習 react+webpack ,偶然路過 webpack 官網 ,看到頂部的 LOGO ,就很感興趣。 最近覺得自己 CSS3 過於薄弱,想著深入學習一番,遂以這個 LOGO 為切入口,好好研究學習了一下相關的 CSS3 屬性。webpack 的 LOGO 動畫效果乍看不是很難,深入瞭解之後 ...
  • ...
  • AngularJS HTML DOM AngularJS為HTML DOM 元素的屬性提供了綁定應用數據的指令。 ng-disabled指令 ng-disabled指令直接綁定應用數據到HTML的disabled屬性。 實例: <div ng-app="" ng-init="mySwitch=tru ...
  • github下載地址:https://github.com/CoderMJLee/MJRefresh MJRefresh類結構圖 下拉刷新控制項的種類 預設(Normal):MJRefreshNormalHeader 動圖(Gif):MJRefreshGifHeader 上拉刷新控制項的種類 自動刷新( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...