使用 std::vector<>作为 Objective-C 属性 [英] Using a std::vector<> as an Objective-C property

查看:76
本文介绍了使用 std::vector<>作为 Objective-C 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Objective-C++ 类,我希望它有一个 C++ std::vector 属性.我是这样声明的:

I have an Objective-C++ class that I wish to have a property which is a C++ std::vector<std::string>. I've declared it like this:

@interface WordModel : NSObject

@property std::vector<std::string>  words;

@end

当我尝试向 vector 添加单词时,没有任何反应.例如,在 -init 方法中,我是这样做的:

When I attempt to add words to the vector nothing happens. For example, in the -init method, I'm doing this:

    std::string nextLine;
    while(wordsFile.good())
    {
        std::getline(wordsFile, nextLine);
        if (nextLine.length() > 0)
        {
            self.words.push_back(nextLine);
        }
    }

在调用 push_back() 之后,调试器报告 self.words vector 仍然为空.为什么?在编译期间或运行时都没有错误消息.

After calling push_back() the debugger reports the self.words vector as still being empty. Why? There are no error messages either during compilation or at runtime.

如果我将属性更改为 ivar,一切都会按预期进行.也就是说,如果我把它变成这样:

If I change the property into an ivar, everything works as expected. That is, if I make it into this:

@interface WordSetModel : NSObject
{
    std::vector<std::string>    words;
}
@end

我很困惑为什么会有这么大的差异.

I'm confused as to why there's such a difference.

推荐答案

Objective-C 属性只是一对可以使用点表示法访问的 getter 和 setter 方法.对于属性 @property std::vector;words;,getter 和 setter 方法是:

An Objective-C property is simply a pair of getter and setter methods that you can access using a dot notation. For a property @property std::vector<std::string> words;, the getter and setter methods would be:

- (std::vector<std::string>)words;
- (void)setWords:(std::vector<std::string>)w;

(我假设您没有实现 getter 和 setter,因此它会自动合成它们.但即使您自己实现它们,我相信它仍然必须具有上述类型签名.)

(I am assuming that you didn't implement the getters and setters, so it auto-synthesized them. But even if you implemented them yourself, I believe it would still have to have the above type signatures.)

当您从 self.words 读取时,这只是调用 getter 的语法糖:[self words].请注意,getter 返回一个 std::vector 按值.我认为那是你的问题.当您按值传递或返回某些内容时,它会被复制.所以你得到了一个向量的临时副本,推送到它,然后丢弃它.底层实例变量中的向量不变.对于能够为您提供一些可以让您更改底层向量的方法,它必须返回给您一个 C++引用",例如 std::vector<std::string>&.我不确定您是否可以使用 Objective-C 属性来做到这一点(我还没有尝试过).

When you read from self.words, that is just syntactic sugar for a call to the getter: [self words]. Notice that the getter returns an std::vector by value. I think that that is your problem here. When you pass or return something by value, it is copied. So you are getting a temporary copy of the vector, pushing to it, and then discarding it. The vector in the underlying instance variable is unchanged. For a method to be able to give you something that can allow you to change the underlying vector, it would have to return to you a C++ "reference", something like std::vector<std::string> &. I am not sure whether you can do that with an Objective-C property (I haven't tried).

这篇关于使用 std::vector&lt;&gt;作为 Objective-C 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆