- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
JXA及其内置的objc桥通过Foundation
对象自动公开$
框架中的枚举和常量;例如:
$.NSUTF8StringEncoding // -> 4
CFString
常量,即
kUTType*
中定义常用
UTI值的
CoreServices
常量,例如uti
kUTTypeHTML
的
"public.html"
。
ObjC.import('CoreServices')
导入它们,但它们的字符串值(很容易)不可访问,可能是因为其类型为
CFString[Ref]
:
ObjC.import('CoreServices') // import kUTType* constants; ObjC.import('Cocoa') works too
$.kUTTypeHTML // returns an [object Ref] instance - how do you get its string value?
ObjC.unwrap($.kUTTypeHTML)
不起作用,也不起作用。
ObjC.unwrap($.kUTTypeHTML[0])
来定义可以解决问题的
.deepUnwrap()
函数的绑定,例如
ObjC.bindFunction()
或
CFString*()
,但如何翻译objc签名对我来说并不明显。
最佳答案
虽然我不明白所有的含义,但以下似乎是可行的:
$.CFStringGetCStringPtr($.kUTTypeHTML, 0) // -> 'public.html'
# Alternative, with explicit UTF-8 encoding specification
$.CFStringGetCStringPtr($.kUTTypeHTML, $.kCFStringEncodingUTF8) // ditto
kUTType*
常量被定义为
CFStringRef
,
CFStringGetCStringPtr
以指定的编码返回
CFString
对象的内部c字符串(如果可以提取
"with no memory allocations and no copying, in constant time"-或者
NULL
否则)。
NULL
),通过c数据类型映射到jxa数据类型,它可以直接在javascript中使用:
$.CFStringGetCStringPtr($.kUTTypeHTML, 0) === 'public.html' // true
CFString
对象,即使它们可以是
NSString
的“免费桥接”,jxa确实可以识别这种类型。
CFString
来验证JXA不知道
NSString
和
$.NSString.stringWithString($.kUTTypeHTML).js
的等价性,它应该返回输入字符串的副本,而不是用
-[__NSDictionaryM length]: unrecognized selector sent to instance
失败。
CFString
是我们的出发点:
$.kUTTypeHTML
是
CFString[Ref]
类型,但是JXA不返回它的JS字符串表示,只有
[object Ref]
。
CFString
还有另一个副作用,即调用接受泛型类型的
CF*()
函数(或者调用接受jxa不知道的免费桥接
CF*
类型的cocoa方法):
CFDictionary
实例中,其唯一条目具有键
type
,关联值包含原始对象。
$.NSString.stringWithString()
调用失败的原因:它是通过
CFDictionary
包装器而不是
CFString
实例传递的。
CFGetTypeID()
函数,它需要一个
CFTypeRef
参数:即任何
CF*
类型。
CFStringRef
参数作为
CFTypeRef
参数传递是错误的,它错误地执行了上述包装,并有效地通过了
CFDictionary
实例而不是:
$.CFGetTypeID($.kUTTypeHTML) // -> !! 18 (CFDictionary), NOT 7 (CFString)
CF*
函数,可以使用
ObjC.bindFunction()
重新定义感兴趣的函数,从而绕过默认行为:
// Redefine CFGetTypeID() to accept any type as-is:
ObjC.bindFunction('CFGetTypeID', ['unsigned long', [ 'void *']])
$.CFGetTypeID($.kUTTypeHTML)
正确返回
7
(
CFString
)。
$.CFGetTypeID()
返回js
Number
实例,而原始返回一个基础数的字符串表示(
CFTypeID
value)。
CF*
实例的特定类型,请使用
CFShow()
,例如:
$.CFShow($.kUTTypeHTML) // -> '{\n type = "{__CFString=}";\n}'
CFShow()
不返回任何内容,而是直接打印到stderr,因此无法在js中捕获输出。
CFShow
重新定义
ObjC.bindFunction('CFShow', ['void', [ 'void *' ]])
,以免显示包装字典。
CFBoolean
为
false
);对于未知的并因此包装的实例,您将看到上述包装器结构。
// Note: CFShow() prints a description of the type of its argument
// directly to stderr.
$.CFShow($.kUTTypeHTML) // -> '{\n type = "{__CFString=}";\n}'
// Alternative that *returns* the description as a JS string:
$.CFStringGetCStringPtr($.CFCopyDescription($.kUTTypeHTML), 0) // -> (see above)
ObjC.deepUnwrap($.NSDictionary.dictionaryWithDictionary( $.kUTTypeHTML ))
NSDictionary
实例的类型名作为字符串获取。
CFDictionary
的必要重新定义,我们将得到以下结果:
{"type":"{__CFString=}"}
而不是
type
。
CFString
和
CF*
都返回调用方必须释放的对象,并且我不知道JXA是否/如何/何时进行。
/*
Returns the type name of the specified CF* (CoreFoundation) type instance.
CAVEAT:
* A HACK IS EMPLOYED to ensure that a value is consistently returned f
those CF* types that correspond to JS primitives, such as CFNumber,
CFBoolean, and CFString:
THE CODE IS CALLED IN A TIGHT LOOP UNTIL A STRING IS RETURNED.
THIS SEEMS TO WORK WELL IN PRACTICE, BUT CAVEAT EMPTOR.
Also, ON OCCASION A RANDOM CHARACTER APPEARS AT THE END OF THE STRING.
* Only pass in true CF* instances, as obtained from CF*() function
calls or constants such as $.kUTTypeHTML. Any other type will CRASH the
function.
Example:
getCFTypeName($.kUTTypeHTML) // -> 'CFString'
*/
function getCFTypeName(cfObj) {
// Redefine CFGetTypeID() so that it accepts unkown types as-is
// Caution:
// * ObjC.bindFunction() always takes effect *globally*.
// * Be sure to pass only true CF* instances from then on, otherwise
// the function will crash.
ObjC.bindFunction('CFGetTypeID', [ 'unsigned long', [ 'void *' ]])
// Note: Ideally, we'd redefine CFCopyDescription() analogously and pass
// the object *directly* to get a description, but this is not an option:
// ObjC.bindFunction('CFCopyDescription', ['void *', [ 'void *' ]])
// doesn't work, because, since we're limited to *C* types, we can't describe
// the *return* type in a way that CFStringGetCStringPtr() - which expects
// a CFStringRef - would then recognize ('Ref has incompatible type').
// Thus, we must first get a type's numerical ID with CFGetTypeID() and then
// get that *type*'s description with CFCopyTypeIDDescription().
// Unfortunately, passing the resulting CFString to $.CFStringGetCStringPtr()
// does NOT work: it yields NULL - no idea why.
//
// Using $.CFStringCreateExternalRepresentation(), which yields a CFData
// instance, from which a C string pointer can be extracted from with
// CFDataGetBytePtr(), works:
// - reliably with non-primitive types such as CFDictionary
// - only INTERMITTENTLY with the equivalent types of JS primitive types
// (such as CFBoolean, CFString, and CFNumber) - why??
// Frequently, and unpredictably, `undefined` is returned.
// !! THUS, THE FOLLOWING HACK IS EMPLOYED: THE CODE IS CALLED IN A TIGHT
// !! LOOP UNTIL A STRING IS RETURNED. THIS SEEMS TO WORK WELL IN PRACTICE,
// !! BUT CAVEAT EMPTOR.
// Also, sometimes, WHEN A STRING IS RETURNED, IT MAY CONTAIN A RANDOM
// EXTRA CHAR. AT THE END.
do {
var data = $.CFStringCreateExternalRepresentation(
null, // use default allocator
$.CFCopyTypeIDDescription($.CFGetTypeID(cfObj)),
0x08000100, // kCFStringEncodingUTF8
0 // loss byte: n/a here
); // returns a CFData instance
s = $.CFDataGetBytePtr(data)
} while (s === undefined)
return s
}
关于objective-c - JXA:从CoreServices访问CFString常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33314614/
如何编译它? 在此函数的第二行: func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWi
我使用此代码获取 ABPerson 的姓氏 CFStringRef lastNameRef = ABRecordCopyValue((ABRecordRef)personRecordRef, kABP
我想在子函数中为 CFString 分配空间。像这样: void fun(CFStringRef *ref) { ref = CFStringCreateWithCString(NULL, "
我正在为 iPhone 开发应用程序,遇到了一些内存管理问题。在应用程序执行期间,事件字节数不断增加而不受限制。我试图在我的代码中找出问题,但似乎找不到任何会导致事件字节数急剧增加的东西。我在执行过程
不知何故,下面的代码使我的应用程序崩溃: NSString *filename = [NSString stringWithFormat:@"%@%@", dbPath, @"BAR"]; NSStr
我正在开发的一个应用程序在 iPhone 上运行时不断崩溃,但在模拟器上却没有(尽管在没有符号 malloc_error_break 的情况下运行时会显示警告,但该应用程序在 Sim 上仍然运行) 我
我想知道一个字符串是否是单字节编码。 CFShowStr 可以完成这项工作,但它将消息输出到控制台。 CFShowStr 函数输出消息如下所示,IsEightBit 项就是我想要的: Length 7
我有一个CFMutableDictionaryRef ,调试器中的部分内容是: "device-id" = ; model = ; "vendor-id" = ; 现在我可以获得 key model
我正在应用程序上运行仪器。根据仪器,未检测到任何泄漏。 但是,类别CFString (store) 一直在上升。有谁知道 CFString (store) 是什么? 这是否意味着我有泄漏? 最佳答案
我看过问答 here about the self keyword in Swift . 但是,对我来说,这并不能解释在 this question 的以下代码片段中使用 .self let attr
我有以下代码将 String 转换为 CFString 和 backwarts: string path = @"C:\Users\ayi\Desktop\Failed\AngryBirds.ipa"
在 xcode 中使用内存图调试器时,我看到了一些内存泄漏。 Backtrace 没有直接链接到我的任何代码,而是通过跟踪猜测它的保存以假设它与组合和一些 DataTaskPublisher 相关。
首先,这与古代技术有关。我正在处理的程序端口在 Metrowerks Codewarrior 9 中维护,目标是 PPC。 用于 MSL C 的 FSRefParentAndFilename_fope
这个问题在这里已经有了答案: NSString is exactly the same as CFString? (1 个回答) 关闭 9 年前。 我没有理解 iOS 中 CFString 和 NS
我很快就开始使用 Cocoa 编程 Mac OS X 应用程序,所以这确实是一个新问题。为此事道歉。 首先我的代码片段: - (id)tableView:(NSTableView *)tableVie
自 Swift 2 起,可以从 Swift 调用采用 C 回调的 C 函数,而无需中间包装器。 许多 C 事件处理 API 都遵循首先创建上下文的模式: struct Context { CF
我正在尝试掌握在 Mac OS X 中使用 JNA 的窍门。我想访问 Carbon 库,但 Cocoa 没有对应的库,因此 Rococoa 无法帮助我(我认为...) 当我尝试调用需要 CFStrin
我有一个返回 CFString 的库,我试图在 C# 中获取该字符串值。问题是我不知道如何在 C# 中执行此操作。 使外部函数返回 CFString 将不起作用,因为它会引发异常“传递给非托管代码的类
我正在解决我的 iPad 应用程序中的一些内存分配问题,并且花了很长时间观察 CFString 在zombies instrument,直到我切换到 Leaks or allocations inst
我最近更新到 Xcode 6.1 以便能够与 iOS 8.1 一起工作,但现在我的最新项目面临错误。 对于以下行,我收到错误消息“CFString!不符合协议(protocol) Hashable”:
我是一名优秀的程序员,十分优秀!