理解_bridge

3509 ワード

比較的に使用されて、全文は転載して、原文はこれをクリックします
なぜObject-C++を使うのか
iOSの開発では、OCとC++の混成が避けられない状況があります.一つはプログラムの計算性能の向上を担当するためです.二つ目は、いくつかの3つのオープンソースライブラリがC++で書かれているためです.この2つの原因も私にC++をマスターすることを決意させた要素です.結局、オープンソースこそ王道で、OCだけを書いているのに、その真相を見ることができません.確かにつらいです.ドアの外にとどまらせ、井戸に座って天を見るしかない.
ブリッジとは?
ブリッジは,object−cがARC環境下で開発した変換CポインタとOCクラスポインタとして用いられる変換技術である.もちろん、この技術はMRCには存在しません.つまりブリッジはARCの連帯産物です.ARCは私たちのプログラマーの両手を解放したので、もちろんメモリの概念が薄れたので、ARCが業界に受け入れられない前に多少気持ち悪いです.
ブリッジで使用する3つの方法:
(__bridge ) (__bridge_retained ) (__bridge_transfer ))
ブリッジ方法の用途:
__bridge:通常のCポインタとOCポインタの変換として使用され、何の操作もしません.
void *p;
NSObject *objc = [[NSObject alloc] init];
p = (__bridge void*)objc;

ここでのvoid*pポインタはNSObject*objcというOCクラスを直接指しており,pポインタはOCオブジェクトを持たず,通常のポインタとアドレスを指しているに違いない.OCオブジェクトが解放され、pポインタもGameoverになるという問題が発生しました.
__bridge_retained:CポインタとOCポインタの変換として使用され、変換されたオブジェクトの所有権も使用されます.
では、これはどういう意味ですか.コードを先にご覧ください
@interface ABSClass : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation ABSClass
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        void *p;
        {
            ABSClass *objc = [[ABSClass alloc]init];
            objc.name = @"  ";
            p = (__bridge void*)objc;
        }
        NSLog(@"%@", [(__bridge ABSClass *)p name]);
    }
    return 0;
}

このコードはほぼ上のセグメントと同じように見えますが、役割ドメインにABSClass*objcというオブジェクトを作成し、役割ドメイン外のpでポインタをブリッジ(_bridge)して指向し、ABSClass objc name , 。 , , , NSLog(@”%@”, [(__bridge ABSClass )p name]); 。 , ABSClass objc , , void p objcのメモリを出力します.もちろんクラッシュします.では、次のコードに変更してみましょう.
@interface ABSClass : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation ABSClass
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        void *p;
        {
            ABSClass *objc = [[ABSClass alloc]init];
            objc.name = @"  ";
            p = (__bridge_retained void*)objc;
        }
        NSLog(@"%@", [(__bridge ABSClass *)p name]);
    }
    return 0;
}

プログラムは正常に動作しています.なぜなら、私たちは__を使用しているからです.bridge_retainedはMRCの下のretainに相当し、メモリカウンタを+1し、void*pでメモリを変更するので、*objcが役割ドメインを超えた場合、参照計算機-1は、void*pが参照したメモリを解放しません.
__bridge_Transfer:CポインタとOCポインタの変換として使用され、オブジェクトの所有権を持つと元のオブジェクトの所有権が解放されます.(Cポインタ変換OCオブジェクトポインタのみサポート)
かなり迂回していますが、オブジェクトのリファレンスカウンタ+1を先にしてからリファレンスカウンタ-1を行うと理解できます.次のコードで示します.
@interface ABSClass : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation ABSClass
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        void *p;
        @autoreleasepool {
            ABSClass *obj = [[ABSClass alloc] init];
            obj.name = @"  ";
            p = (__bridge_retained void *)obj;
        }
        id obj = (__bridge_transfer id)p;
        NSLog(@"%@", [(__bridge ABSClass *)p name]);
        NSLog(@"%@", [(ABSClass *)obj name]);
        NSLog(@"Hello, World!");
    }
    return 0;
}

以上のコードは正しく動作し、void*pポインタを実行に変換します.bridge_TransferはOCポインタで、この操作は実際には-(void)setに相当します:操作、MRCに変換するのは以下のコードです:
id obj = (id)p
[obj retain];
[(id)p release];

参照カウンタが常に1であり、1つのretainが1つのreleaseに対応することを保証するために、新しい値retainを次に古い値releaseをreleaseします.
さて、以上の方法はC/C++ポインタとOCオブジェクトポインタの相互変換の紹介であり、より多くのパートナーの理解を助けたいと考えています.