我试图了解NSString从CFStringRefARC 获得一个正确的方法?同为去相反的方向,CFStringRef以NSString在ARC?
在不造成内存泄漏的情况下执行此操作的正确方法是什么?
objective-c nsstring automatic-ref-counting toll-free-bridging
我正在将一个App从Objective-C移植到Swift,我需要使用以下方法:
CFStreamCreatePairWithSocketToHost(alloc: CFAllocator!, host: CFString!, port: UInt32, \
readStream: CMutablePointer<Unmanaged<CFReadStream>?>, \
writeStream: CMutablePointer<Unmanaged<CFWriteStream>?>)
Run Code Online (Sandbox Code Playgroud)
旧的逻辑看起来像这样(几个网站似乎都同意):
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), port, \
&readStream, &writeStream);
NSInputStream inputStream = (__bridge_transfer NSInputStream *)readStream;
NSOutputStream outputStream = (__bridge_transfer NSOutputStream *)writeStream;
Run Code Online (Sandbox Code Playgroud)
由于免费桥接,这很好用.但是,ARC在"Swift-space"中不存在,并且类型系统已经改变.
如何将我的流变成实例
CMutablePointer<Unmanaged<CFReadStream>?>, and
CMutablePointer<Unmanaged<CFWriteStream>?>
Run Code Online (Sandbox Code Playgroud)
然后NSStream在CFStreamCreatePairWithSocketToHost调用之后将它们转换回子类?
我正在尝试在使用CoreFoundation和Foundation的Linux上编译一些代码,但Linux并没有像macOS和iOS那样实现桥接.
Objective-C和Swift工作之间的桥梁:
import Foundation
import CoreFoundation
import Glibc
func wantsNSString(_ string: NSString) {
print(string)
}
let string = "Hello, world!"
wantsNSString(string._bridgeToObjectiveC())
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何桥接到CoreFoundation.我不能只是传递NSString给一个想要一个CFString:
import Foundation
import CoreFoundation
import Glibc
func wantsCFString(_ string: CFString) {
print(string)
}
let string = "Hello, world!"
wantsCFString(string._bridgeToObjectiveC()) //error: cannot convert value of type 'String._ObjectType' (aka 'NSString') to expected argument type 'CFString'
Run Code Online (Sandbox Code Playgroud)
我不能像在macOS上那样投射它:
import Foundation
import CoreFoundation
import Glibc
func wantsCFString(_ string: CFString) {
print(string)
}
let string = "Hello, world!"
wantsCFString(string._bridgeToObjectiveC() as …Run Code Online (Sandbox Code Playgroud) 考虑这个ARC代码:
- (void)main {
NSString *s = [[NSString alloc] initWithString:@"s"];
[NSApp beginSheet:sheet
modalForWindow:window
modalDelegate:self
didEndSelector:@selector(sheetDidEnd:returnCode:context:)
contextInfo:(__bridge void *)s
];
}
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode context:(void *)context {
NSString *s = (__bridge_transfer NSString *)context;
}
Run Code Online (Sandbox Code Playgroud)
问题:在第7行,应该__bridge使用,或者__bridge_retained,或者无关紧要,或者选择是否依赖于字符串的保留计数(即,是否显式分配字符串与是否通过类初始化程序自动释放+[NSString stringWithString:]?
memory-management objective-c retaincount automatic-ref-counting toll-free-bridging
好吧,这是我在使用CGImageSource时遇到的情况,并注意到CFDictionary和NSDictionary之间的免费桥接在某些情况下似乎遇到了问题.我已设法构建以下示例以显示我的意思:
func optionalProblemDictionary() -> CFDictionary? {
let key = "key"
let value = "value"
var keyCallBacks = CFDictionaryKeyCallBacks()
var valueCallBacks = CFDictionaryValueCallBacks()
let cfDictionary = CFDictionaryCreate(kCFAllocatorDefault, UnsafeMutablePointer(unsafeAddressOf(key)), UnsafeMutablePointer(unsafeAddressOf(value)), 1, &keyCallBacks, &valueCallBacks)
return cfDictionary
}
Run Code Online (Sandbox Code Playgroud)
相当简单(有点傻)但它的功能返回和可选的CFDictionary.尝试从此函数创建NSDictionary时,"fun"开始:
以下为什么不工作?
if let problemDictionary = optionalProblemDictionary() as? NSDictionary {
print(problemDictionary) // never enters, no warnings, compiles just fine
}
Run Code Online (Sandbox Code Playgroud)
虽然这很好吗?
if let cfDictionary = optionalProblemDictionary() {
let problemDictionary = cfDictionary as NSDictionary
print(problemDictionary)
}
Run Code Online (Sandbox Code Playgroud)
XCode 7.0(7A220)
这个问题与我的相似,但不包含答案.我想把一个转换CFIndex成一个NSInteger.我已经检查了具有免费桥接的类型列表,这不是其中之一.
objective-c type-conversion core-foundation nsinteger toll-free-bridging
我正在使用Chipmunk物理引擎编写游戏,我想在每个人体的userData场中存储指向Objective-C对象的指针.我知道我需要使用桥接投之间投id与void *,但我不知道我在做它的方式是安全的:
// When body is created
cpBody *body = cpBodyNew(...);
UserData *userData = [[UserData alloc] init];
cpBodySetUserData(body, CFBridgingRetain(body));
...
// When body is destroyed
UserData *userData = cpBodyGetUserData(body);
CFBridgingRelease(userData);
cpBodyFree(body);
Run Code Online (Sandbox Code Playgroud)
这段代码似乎有用,但我也读到你只应该使用CFBridging*()可以免费桥接到Core Foundation类型的对象.既然UserData是免费的桥接类型NSObject,而NSObject不是免费的桥接类型列表,我似乎打破了这个规则.
我的代码是否可以,因为我最终调用CFBridgingRelease并且不尝试将对象传递给任何其他Core Foundation函数,或者是否有其他方法我应该将Objective-C对象传入和传出C?
c objective-c chipmunk automatic-ref-counting toll-free-bridging
我很想在我的项目中加入arc.我正在尝试理解__bridge及其小朋友,以便在从容器中添加和删除它时可以正确地投射我的CGImageRef.
我在我的一条线上得到了"存储对象的潜在泄漏......".这是我的代码的基本循环:
CGImageRef renderedRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
[_array addObject: (__bridge_transfer id)renderedRef];//_array is an iVar
Run Code Online (Sandbox Code Playgroud)
然后在某个地方,我这样做:
CGImageRef iRef = (__bridge_retained CGImageRef)array[0];
//then I do something fancy with iRef
//at the end of the method, I get "Potential leak of an object stored…"
//I have no idea what to do
//I've tried CGImageRelease(iRef); but it still doesn't change the warning.
Run Code Online (Sandbox Code Playgroud)
有人可以对此有所了解吗?另外,我尝试过只使用__bridge,但这没有什么区别.
编辑1:
我扩展了分析仪结果并跟踪发生的情况.这是因为我在这样的方法中使用iRef:[self doSomethingFancy:iRef]; 在那种方法中,iRef被保留但未被释放.所以这修复了警告,但我仍然有点困惑.
关于何时使用各种__bridge演员,我不是很清楚.在ARC下,以下是否增加了引用计数?
CGImageRef iRef = (__bridge CGImageRef)array[0];
Run Code Online (Sandbox Code Playgroud)
此外,在某些时候,如果我告诉我的_array iVar删除AllObjects,那会减少他们的引用计数吗?
objective-c ios cgimageref automatic-ref-counting toll-free-bridging
objective-c ×6
swift ×3
c ×1
cfdictionary ×1
cgimageref ×1
chipmunk ×1
foundation ×1
ios ×1
linux ×1
nsdictionary ×1
nsinteger ×1
nsstring ×1
retaincount ×1
swift2 ×1