iOS / Objective-C: Попытка отсканировать строку на наличие подстрок, которые будут назначены нескольким NSStrings - PullRequest
3 голосов
/ 08 июля 2011

Я пытаюсь выполнить задание «Flickr Fetcher» Стэнфордского программирования iPhone (FA10) - пока все идет хорошо, но я зашел в тупик:

Я успешно извлек локациюиз «100 лучших» картинок, которые оформлены в строку как «Страна, Штат, Город».Я хотел бы создать две строки NSS - одна страна, другая строка штат и город.Откуда я могу сделать

cell.textLabel.text = countryString;
cell.detailTextLabel.text = stateCityString;

в методах источника данных моего табличного представления.

Из исследований на stackoverflowи Apple Documentaion , NSScanner, кажется, моя лучшая ставка - вот что я имею до сих пор ...

- (void)viewDidLoad {
    //Get the top 100 photos from Flickr
    self.topPlacesArray = [FlickrFetcher topPlaces];

    NSString *mainLabelString = [[NSString alloc] init];
    NSString *stringFromArray = [[NSString alloc] init];

    //This retrieves the string of the location of each photo
    stringFromArray = [topPlacesArray valueForKey:@"_content"];

    NSScanner *theScanner = [NSScanner scannerWithString:stringFromArray];
    NSCharacterSet *commaSet = [[NSCharacterSet alloc] init];
    commaSet = [NSCharacterSet characterSetWithCharactersInString:@","];

    while ([theScanner isAtEnd] == NO) {
        if ([theScanner scanUpToCharactersFromSet:commaSet intoString:&stringFromArray]) {
            NSLog(@"%@",stringFromArray);
        }
    }

Я просто пытаюсь проверить, правильно ли строкаСам подстроки - однако я получаю «SIGBART» в начале цикла while, ошибка такова:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0x8939eb0'

Из всей документации, которую я видел на NSScanner, кажется, что она установленаоднако, независимо от того, какие изменения я делаю, кажется, что он не может даже начать цикл.

Что мне нужно сделать, чтобы правильно настроить NSScanner, чтобы избежать "SIGABRT"?(для записи, я предполагаю, что "SIGABRT" - это ошибка?).Спасибо всем за ваше время, вы все лучшие!

(Кстати: я знаю, что это еще не полностью реализовано как для страны, так и для штата, я просто хочу привыкнуть к NSScanner, остальное я реализую, как только получу контроль NSScanner)

РЕДАКТИРОВАТЬ 1: SosBorn!Ты потрясающая!Спасибо вам большое!Итак, я реализовал это для моего viewDidLoad:

- (void)viewDidLoad
{
    self.topPlacesArray = [FlickrFetcher topPlaces];
    NSArray *ArrayOfStrings = [[NSArray alloc] init];
    NSArray  *placeElements = [[NSArray alloc] init];
    NSString *country = [[NSString alloc] init];
    NSString *city = [[NSString alloc] init];
    NSString *state = [[NSString alloc] init];

    ArrayOfStrings = [topPlacesArray valueForKey:@"_content"];

    for (NSString *place in ArrayOfStrings) {

        placeElements = [place componentsSeparatedByString:@", "];
        if ([placeElements count] == 3 && [placeElements objectAtIndex:0] != nil) {
           city = [placeElements objectAtIndex:0];
           [self.cityArray addObject:city];
           state = [placeElements objectAtIndex:1];
           [self.stateArray addObject:state];
           country = [placeElements objectAtIndex:2];
           [self.countryArray addObject:country];
           NSLog(@"%@, %@, %@", city, state, country);    
        }
       else {
           NSLog(@"Did this work?");
       }
    }

    [ArrayOfStrings release];
    [placeElements release];
    [country release];
    [city release];
    [state release];
    [super viewDidLoad];
}

Это сработало как полный шарм, НО у меня какой-то плохой доступ происходит в Делегате при попытке доступа к self.window.rootViewController = self.viewController - это неиметь какой-либо смысл (у меня на самом деле полностью пустая таблица и т. д.) - поэтому я думаю, что я играл с плохим управлением памятью с помощью подстроки, и теперь у него возникают проблемы с этим вызовом делегата.

Чак, меня очень заинтересовал ваш комментарий, так как меня учили, что правильный способ создания переменных - это вызвать [myclass alloc] init];и затем отпустите, когда вы закончите - как я.Конечно, моя цель-C зеленость показывает немного ... румянец .

Вы все, и это невероятное сообщество является таким активом для нас, студентов, спасибо за ваше время и преданность делу.Единственный путь к прогрессу - это путь сотрудничества!

РЕДАКТИРОВАТЬ 2: Хорошо - теперь он полностью исправлен без каких-либо проблем с утечкой.Чак ты был прав!У меня в голове были целиком и полностью перемешаны ресурсы alloc init - вот мое окончательное решение:

    NSMutableArray *array1 = [[NSMutableArray alloc] init];
NSMutableArray *array2 = [[NSMutableArray alloc] init];
NSMutableArray *array3 = [[NSMutableArray alloc] init];

self.cityArray = array1;
self.countryArray = array2;
self.stateArray = array3;

[array1 release];
[array2 release];
[array3 release];


NSArray *ArrayOfStrings = [topPlacesArray valueForKey:@"_content"];
NSArray *topPlaces = [NSArray arrayWithArray:ArrayOfStrings];
NSArray *topPlacesSorted = [topPlaces sortedArrayUsingSelector:@selector(compare:)];
ArrayOfStrings = topPlacesSorted;

for (NSString *place in ArrayOfStrings) {
    NSArray *placeElements = [place componentsSeparatedByString:@", "];
    if ([placeElements count] == 3 && [placeElements objectAtIndex:0] != nil) {

        NSString *city = [placeElements objectAtIndex:0];

        [self.cityArray addObject:city];

        NSString *state = [placeElements objectAtIndex:1];

        [self.stateArray addObject:state];

        NSString *country = [placeElements objectAtIndex:2];

        NSString *stateAndCountry = [NSString stringWithFormat:@"%@, %@", state, country];

        [self.countryArray addObject:stateAndCountry];

        NSLog(@"%@, %@, %@", city, state, country);    
    }
   else {
       NSLog(@"Nil Request");
   }

Еще раз спасибо, SosBorn, я чувствовал, что забыл основы CS ಠ_ಠ.Единственное, что меня действительно беспокоит, так это то, почему мы должны инициализировать экземпляр NSMutableArrays таким образом - я обнаружил, что это был only способ заставить их работать на самом деле.

1 Ответ

1 голос
/ 08 июля 2011

Не совсем уверен, почему происходит сбой, но я думаю, что другой подход к этому послужит вам лучше.У вас есть topPlacesArray, почему бы не перебрать массив и обработать каждую запись массива отдельно?Я делаю некоторые предположения относительно topPlacesArray, но это выглядело бы примерно так:

for (NSString *place in topPlacesArray)
{
  //Place is probably in this format: "Country, State, City"
  NSArray *placeElements = [place componentsSeperatedByString:@","];
  //This should give you an array with three elements. Country State and city.
  NSString *country = [placeElements objectAtIndex:0];
  NSString *cityState = [NSString stringWithFormat:@"%@, %@", country, cityState];
  //Now you have your strings that you need. Do whatever you need to do with them.
  //Add them to an array or set the value of a text label, etc.
}

Не заняло времени на управление памятью, но вы поняли идею.

...