Задача C заполнить вектор. Push_back не работает - PullRequest
0 голосов
/ 10 мая 2018

Я начинающий разработчик Objetive C и пытаюсь заполнить вектор, который является свойством переменной ... Но он не работает, я не могу понять, почему или как это исправить

-(void) setUpLabels:(NSString *) _labels_path {
    // Read the label list
    self.label_strings.clear();
    std::vector<std::string> new_values;
    std::ifstream t;
    t.open([_labels_path UTF8String]);
    std::string line;
    while (t) {
        std::getline(t, line);
        new_values.push_back(line);
    }
    self.label_strings.reserve(new_values.size());
    for (int index = 0; index  < new_values.size(); index++) {
        self.label_strings.push_back(new_values[index]);
    }
    NSLog(@"size=%lu",self.label_strings.size());
    t.close();

}

Это файл .h

@interface AIClassifier: Classifier
@property std::vector<std::string> label_strings;

    - (id) init;
    - (id) initWithParams:(NSString *)model:(NSString *) labels;
@end

Функция setUpLabels отсутствует в файле ..

Все время размер печати = 0. Я пробовал более простые версии с тем же результатом.

1 Ответ

0 голосов
/ 10 мая 2018

Одна проблема с этим кодом заключается в том, что вы используете @property и self.label_strings. @property создает метод получения, который возвращает значение типа std::vector<std::string>. Это значение, а не указатель / ссылка, поэтому это будет новая копия базового объекта. Это означает, что каждый раз, когда вы вызываете self.label_strings.push_back(x) или любой другой метод, он работает с копией исходного объекта (который всегда пуст).

Чтобы решить эту проблему, используйте _label_strings вместо self.label_strings или используйте переменную экземпляра для label_strings вместо @property:

@interface AIClassifier: Classifier {
    std::vector<std::string> label_strings;
}
@end

(Примечание: лучше переместите это как частную переменную экземпляра в вашем файле .mm)

Если нет особой причины использовать C ++ для этой задачи, существует несколько способов Objective-C для чтения файла построчно.

Если файл небольшой, вы можете полностью прочитать его в память, а затем разбить на отдельные строки, как здесь: https://stackoverflow.com/a/4466934/1009546

В Objective-C мы используем NSArray<NSString*>* вместо std::vector<string>.

Другая вероятная причина, по которой вы ничего не получаете, в том, что либо неверный путь к файлу _labels_path, либо его нет на устройстве.

Вы можете установить точку останова в этой функции и использовать пошаговый отладчик Xcode, чтобы увидеть, что на самом деле происходит и что у вас есть в _labels_path и new_values ​​во время выполнения.

Обычно вам обычно не нужно использовать C ++ в Objective-C, особенно не в интерфейсах. Если вы сделаете свой файл ".m", а не ".mm", это не позволит C ++ внутри (только Objective-C).

Примечание 1: если вы придерживаетесь C ++, вам не нужен второй цикл. Просто присвоение self.label_strings = new_values; скопирует его (это магия C ++).

Примечание 2: всегда проверяйте файл после его открытия. В Objective-C у вас обычно NSError* возвращается из функций. В C ++ вы можете проверить бит неудачи (см. пример открытых документов ).

Примечание 3: В идеале используйте RAII , чтобы убедиться, что файл закрыт. В этом случае t.close(); не требуется, потому что деструктор ifstream закроет его (см. http://www.cplusplus.com/reference/fstream/ifstream/close/).

...