首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弧中的NSFastEnumeration对象铸造

弧中的NSFastEnumeration对象铸造
EN

Stack Overflow用户
提问于 2013-06-15 05:56:59
回答 1查看 631关注 0票数 2

我试图在自定义类上实现来自NSFastEnumeration协议的NSFastEnumeration方法。

到目前为止,我已经正确地迭代了我的对象,但是返回的对象不是objects对象,而是核心的基础等价物。

下面是设置state->itemsPtr的代码的一部分:

MyCustomCollection.m

代码语言:javascript
复制
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
                                   objects: (id __unsafe_unretained *)buffer
                                     count: (NSUInteger)bufferSize {

    // ... skip details ...

    NSLog(@"Object inside method: %@", someObject);
    state->itemsPtr = (__unsafe_unretained id *)(__bridge void *)someObject;      

    // ... skip details ...
}

然后,我调用'for..in‘循环在其他地方,像这样

SomeOtherClass.m

代码语言:javascript
复制
MyCustomCollection *myCustomCollection = [MyCustomCollection new];
[myCustomCollection addObject:@"foo"];
for (id object in myCustomCollection) {
    NSLog(@"Object in loop: %@", object);
}

控制台输出是:

代码语言:javascript
复制
Object inside method: foo
Object in loop: __NSCFConstantString

正如您所看到的,在NSFastEnumeration协议方法中,对象可以很好地打印,但是一旦它被转换成id __unsafe_unretained *,我就失去了原始的目标-C对应的类。

老实说,在这种情况下,我不太确定(__unsafe_unretained id *)(__bridge void *)转换是如何工作的。(__unsafe_unretained id *)似乎与正确类型的itemsPtr需要匹配。(__bridge void *)似乎转换为一个类型为void的指针,__bridge用来将obj-c世界连接到CF世界。根据llvm文档,对于__bridge

不存在所有权转移,ARC不插入任何保留操作。

对吗?

根据我的理解,__NSCFConstantString只是NSString的核心基础。我还了解到,使用ARC,您需要从objects对象过渡到CoreFoundation等效对象,因为ARC不知道如何管理后者的内存。

如何才能使“for..in”循环中的对象具有原始类型?

还请注意,在本例中,我将NSStrings添加到我的集合中,但理论上它应该支持任何对象。

更新

Rob的回答是正确的,但是为了验证这一理论,我将for循环改为:

代码语言:javascript
复制
for (id object in myCustomCollection) {
    NSString *stringObject = (NSString *)object;
    NSLog(@"String %@ length: %d", stringObject, [stringObject length]);
}

理论上,这应该可以工作,因为对象是等价的,但它崩溃时出现了以下错误:

代码语言:javascript
复制
+[__NSCFConstantString length]: unrecognized selector sent to class

看起来,for循环中返回的对象几乎是类,而不是实例。这里可能有其他问题..。对此有什么想法吗?

更新2:解决方案

它很简单:(多亏了CodaFi

代码语言:javascript
复制
state->itemsPtr = &someObject;
EN

回答 1

Stack Overflow用户

发布于 2013-06-15 06:07:54

您的代码是好的方式。您的调试输出显示了一个实现细节。

--这意味着您可以将任何NSString视为CFString,反之亦然,只需将指针转换为另一种类型。

实际上,在幕后,编译时常量字符串是__NSCFConstantString类型的实例,这就是您所看到的。

如果将@"hello"放入源代码中,编译器将其视为NSString *并将其编译为__NSCFConstantString的实例。

如果将CFSTR("hello")放入源代码中,编译器将其视为CFStringRef并将其编译为__NSCFConstantString的实例。

在运行时,内存中的这些对象之间没有区别,即使您在源代码中使用了不同的语法来创建它们。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17120667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档