user1118321
user1118321

Reputation: 26385

Using a std::vector<> as an Objective-C property

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

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);
        }
    }

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.

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.

Upvotes: 3

Views: 1660

Answers (1)

newacct
newacct

Reputation: 122479

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;

(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.)

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).

Upvotes: 9

Related Questions