Objective-C和其他C指针的转换

首先看一下典型的NSString与CFStringRef的相互转换

http://www.tuicool.com/articles/MJRr226

// CFStringRef to NSString *
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;

// NSString * to CFStringRef
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;

// CFStringRef to NSString *

NSString * yourFriendlyNSString = ( __bridge NSString * ) yourFriendlyCFString ;

// NSString * to CFStringRef

CFStringRef yourFriendlyCFString = ( __bridge CFStringRef ) yourFriendlyNSString ;

上面出现了一个关键字 __bridge ,这个关键字便是整个转换的关键。Apple官方对于 __bridge 的解释如下:

**__bridge** transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

**__bridge_retained** or **CFBridgingRetain** casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you. You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

**__bridge_transfer** or **CFBridgingRelease** moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC. ARC is responsible for relinquishing ownership of the object.

上面这些话总结起来就是:

  • __bridge 用于Objective-C和Core Foundation指针之间的转换,这种转换不会更换对象的所有权(ownership)。
  • __bridge_retained 或 CFBridgeRetain 用于从Objective-C到Core Foundation的指针转换,并且会将对象的所有权(ownership)转移,所以你需要在不再使用该对象的时候调用CFRelease方法来解除引用。
  • __bridge_transfer 或 CFBridgeRelease 用于将非Objective-C指针转换为Objective-C指针,对象的所有权(ownership)会交给ARC,这时你无须担心对象何时释放,交给ARC去做就好了。

为什么在使用__bridge_retained进行转换时需要自己调用CFRelease来释放对象,其实原因很简单:Core Foundation的对象在ARC的管辖范围之内。

下面是示例代码:

// Don‘t transfer ownership. You won‘t have to call `CFRelease`
CFStringRef str =(__bridge CFStringRef)string;
// Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you‘re done with it
CFStringRef str =(__bridge_retained CFStringRef)string; // you will have to call `CFRelease`

// Don‘t transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)
NSString*string =(__bridge NSString*)str;
// Transfer ownership to ARC. ARC kicks in and it‘s now in charge of releasing the string object. You won‘t have to explicitly call `CFRelease` on `str`
NSString*string =(__bridge_transfer NSString*)str;

// Don‘t transfer ownership. You won‘t have to call `CFRelease`

CFStringRef str = ( __bridge CFStringRef ) string ;

// Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you‘re done with it

CFStringRef str = ( __bridge_retained CFStringRef ) string ; // you will have to call `CFRelease`

// Don‘t transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)

NSString* string = ( __bridge NSString* ) str ;

// Transfer ownership to ARC. ARC kicks in and it‘s now in charge of releasing the string object. You won‘t have to explicitly call `CFRelease` on `str`

NSString* string = ( __bridge_transfer NSString* ) str ;

时间: 2024-08-14 06:37:33

Objective-C和其他C指针的转换的相关文章

对象布局已知时 C++ 对象指针的转换时地址调整

在我调试和研究 netscape 系浏览器插件开发时,注意到了这个问题.即,在对象布局已知(即对象之间具有继承关系)时,不同类型对象的指针进行转换(不管是隐式的从下向上转换,还是强制的从上到下转换)时,编译器会根据对象布局对相应的指针的值进行调整.不管是 microsoft 的编译器,还是 gcc 编译器都会做这个动作,因为这和 C++ 对象模型有关. 举一个简单的例子,如下代码: #include <stdio.h> class A { public: int x; void foo1()

golang的指针到string,string到指针的转换

由于某个需求,需要如题的转换,废话不多说,直接贴代码了,其实挺丑了,备用了 func (this *Server) socketParserHandler(client *genTcpServer.Client, fullData []byte) { fmt.Println("original data is", client) strPointerHex := fmt.Sprintf("%p", unsafe.Pointer(client)) fmt.Printl

void指针的转换(2)

void类型指针能够通过显式转换为具有更小或同样存储对齐限制的指针.但数据可能失真.所谓"同样存储对齐限制"是指void类型指针所指的数据在内存中所占的长度与显式转换后的指针所指的数据在内存中所占的长度相等,比方以上程序中的p1所指的原数据在内存中占2个字节,p2所指的数据在内存中也是占两个数据. 但应注意的是.仅仅有上面的这样的转换前后指针所指数据类型一致的转换才保持数据不失真,假设类型不一致,即使具有同样存储对齐限制,也有可能失真,比方由short转向unsigned short,

在Golang里如何实现结构体成员指针到结构体自身指针的转换

原文地址:http://goworldgs.com/?p=37 在C语言中有一个经典的宏定义,可以将结构体struct内部的某个成员的指针转化为结构体自身的指针.下面是一个例子,通过FIELD_OFFSET宏计算结构体内一个字段的偏移,函数getT可以从一个F*的指针获得对应的T*对象. struct F { int c; int d; } struct T{ int a; int b; struct F f; } #define FIELD_OFFSET(type, field) ((int)

派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good

大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree是最底层基类(非虚类), CSamplerTree(虚类)派生自CTree,CMSamplerTree,CASamplerTree派生自CSamplerTree,                                                         CTree中包括两个成员

函数指针的转换 &amp; C的注意点

再让我们看看<signal.h>中声明的signal函数void (*signal(int, void(*)(int)))(int)首先,用typedef简化,typedef void (*handler_type)(int)得,void (*signal(int, handler_type))(int)进一步 handler_type signal(int, handler_type); 记住:数组名是指向该数组首元素的指针如,int a[11];  //那么a的类型为 (int *)int

u8指针强制转换成u32

一个u8类型的数组,指针p指向该数组的第一个元素,p的类型是u8*,指针q也指向该数组的第一个元素,q的类型是u32*,问*p和*q的值是多少? typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8; int main(void) { u8 i; u8 tab[4] = {0x12, 0x34, 0x56, 0x78}; u8 *p = tab; u32 *q = (u32*)p; for

offset 后 指针数组转换

AcDbObjectId pidoffset; AcDbPolyline *plineOffset; AcDbVoidPtrArray ptarr=NULL; pline->getOffsetCurves(dist, ptarr); int ilen = ptarr.length(); for (int i = 0; i < ilen; i++) { plineOffset = static_cast<AcDbPolyline*>(ptarr[i]); pidoffset = CD

指针强制转换

#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { unsigned char a[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44, 0x43}; unsigned int *p = (unsigned int*)a; printf("0x%x\n", *(p + 1)); printf("0x%x\n&