objective-c 指針

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

咱們都知道這樣一個問題,將一個基本數據類型的變量經過函數參數傳入函數內,在函數內如何改變,都不會影響到外部變量的值!以下代碼:指針

#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;
}

a的值仍是等於5,說明函數傳遞的只是一個5的值。那若是要在函數內部改變外部變量的值要怎麼辦呢?固然是用指針了,將指針的值傳入函數,而後在函數中根據指針去找到指向的內存中修改,代碼以下:code

#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;
}

這時a的值是10了,咱們傳入的是內存地址,而後在函數中對地址指向內存進行修改。對象

那麼,若是函數參數自己是一個對象,咱們傳入的是一個對象,自己就是一個地址,會怎樣呢?咱們先新建一個對象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;
}

怎麼樣,輸出結果是XCoder Studio,而不是Web Site。由於咱們傳入函數的是obj這個指針,這個指針指向了內存中的一個MyObject對象,函數中obj.name改變的是這個對象的屬性,當函數中obj = [[MyObject alloc] init];執行後,系統會在內存中新開闢一起存儲空間存儲一個新的MyObject對象,而後將函數中的obj存儲的指針值改成這個新的內存地址,而函數外的obj指針並無改變,仍是指向原來的這個對象的地址。it

那麼咱們如何實如今函數中改變函數外對象呢?就用一個新的指針指向這個對象的指針,也就是咱們說的指向指針的指針。代碼以下:內存管理

#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;
}

這時候就實現了吧!io

標題中所說的NSError *__autoreleasing *都是這樣的,咱們能夠在外面新建一個NSError,當函數運行中有錯誤時,新建一個NSError對象並存儲到咱們新建的這個NSError對象中。咱們就能夠經過這個NSError是否爲nil看函數運行是否出錯!test

相關文章
相關標籤/搜索