objective-c 函數(shù)參數(shù) 傳地址 傳指針

原文:http://www.xcoder.cn/?p=213

首先說明一下題目中的形如部分(NSError *__autoreleasing *),這部分可能剛開始看有點(diǎn)兒理解不了,其實就是這樣的(NSError **),這就表示一個指向指針的指針,__autoreleasing是一個修飾符,表示傳入的是一個通過autorelease方法返回的id對象,這在內(nèi)存管理中用到的。

我們都知道這樣一個問題,將一個基本數(shù)據(jù)類型的變量通過函數(shù)參數(shù)傳入函數(shù)內(nèi),在函數(shù)內(nèi)如何改變,都不會影響到外部變量的值!如下代碼:

#import <Foundation/Foundation.h>
 
void test(int a) {
    a = 10;
}
 
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        int a = 5;
        test(a);
        NSLog(@"a = %i", a);
    }
    return 0;
}

程序運(yùn)行結(jié)果如下:

2017-03-13 15:52:31.829285+0800 RTTest[30879:3148850] a = 5
Program ended with exit code: 0

a的值還是等于5,說明函數(shù)傳遞的只是一個5的值。那如果要在函數(shù)內(nèi)部改變外部變量的值要怎么辦呢?當(dāng)然是用指針了,將指針的值傳入函數(shù),然后在函數(shù)中根據(jù)指針去找到指向的內(nèi)存中修改,代碼如下:

 #import <Foundation/Foundation.h>
  
 void test(int * a) {
     *a = 10;
 }
  
 int main(int argc, const char * argv[])
 {
     @autoreleasepool {
         int a = 5;
         test(&a);
         NSLog(@"a = %i", a);
  
     }
     return 0;
 }

再看看運(yùn)行結(jié)果:

2017-03-13 15:52:31.251470+0800 RTTest[30916:3151576] a = 10
Program ended with exit code: 0 

這時a的值是10了,我們傳入的是內(nèi)存地址,然后在函數(shù)中對地址指向內(nèi)存進(jìn)行修改。

那么,如果函數(shù)參數(shù)本身是一個對象,我們傳入的是一個對象,本身就是一個地址,會怎樣呢?我們先新建一個對象MyObject,然后有一個NSString類型的name屬性,這個代碼我就不貼出來了,直接看main.m的代碼吧!

#import <Foundation/Foundation.h>
 #import "MyObject.h"
  
 void test(MyObject * obj) {
     obj.name = @"XCoder Studio";
  
     obj = [[MyObject alloc] init];
     obj.name = @"Web Site";
 }
  
 int main(int argc, const char * argv[])
 {
     @autoreleasepool {
         MyObject * obj = [[MyObject alloc] init];
         obj.name = @"XCoder";
         test(obj);
  
         NSLog(@"obj.name = %@", obj.name);
     }
     return 0;
 }

看看程序運(yùn)行結(jié)果

2017-03-13 15:52:31.858732+0800 RTTest[30929:3152841] obj.name = XCoder Studio
Program ended with exit code: 0

怎么樣,輸出結(jié)果是XCoder Studio,而不是Web Site。因為我們傳入函數(shù)的是obj這個指針,這個指針指向了內(nèi)存中的一個MyObject對象,函數(shù)中obj.name改變的是這個對象的屬性,當(dāng)函數(shù)中obj = [[MyObject alloc] init];執(zhí)行后,系統(tǒng)會在內(nèi)存中新開辟一塊兒存儲空間存儲一個新的MyObject對象,然后將函數(shù)中的obj存儲的指針值改為這個新的內(nèi)存地址,而函數(shù)外的obj指針并沒有改變,還是指向原來的這個對象的地址。

那么我們?nèi)绾螌崿F(xiàn)在函數(shù)中改變函數(shù)外對象呢?就用一個新的指針指向這個對象的指針,也就是我們說的指向指針的指針。代碼如下:

 #import <Foundation/Foundation.h>
 #import "MyObject.h"
  
 void test(MyObject ** obj) {
  
     *obj = [[MyObject alloc] init];
     (*obj).name = @"Web Site";
 }
  
 int main(int argc, const char * argv[])
 {
     @autoreleasepool {
         MyObject * obj = [[MyObject alloc] init];
         obj.name = @"XCoder";
         test(&obj);
  
         NSLog(@"obj.name = %@", obj.name);
     }
     return 0;
 }

運(yùn)行結(jié)果如下:

2020-03-30 05:57:52.314368+0800 RTTest[30941:3153844] obj.name = Web Site
Program ended with exit code: 0 

這時候就實現(xiàn)了吧!

標(biāo)題中所說的NSError *__autoreleasing *都是這樣的,我們可以在外面新建一個NSError,當(dāng)函數(shù)運(yùn)行中有錯誤時,新建一個NSError對象并存儲到我們新建的這個NSError對象中。我們就可以通過這個NSError是否為nil看函數(shù)運(yùn)行是否出錯!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容