iOS/Objective-C:尝试扫描字符串以查找将分配给多个 NSString 的子字符串
我正在尝试完成斯坦福 iPhone 编程 (FA10) 作业“Flickr Fetcher”——到目前为止,一切进展顺利,但我陷入了僵局:
我已经成功提取了“前 100 张”图片的位置,这格式为“国家、州、城市”字符串。我想创建两个 NSString——一个是国家/地区,另一个字符串是州和城市。然后我可以
cell.textLabel.text = countryString;
cell.detailTextLabel.text = stateCityString;
在我的表视图数据源方法中执行此操作。
来自 <一href="https://stackoverflow.com/questions/4249981/how-do-i-find-non-length-specified-substrings-in-a-string-in-objective-c">研究 < a href="https://stackoverflow.com/questions/6549160/multiple-substrings-in-string"> stackoverflow 和 Apple 文档, 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);
}
}
我只是想看看字符串是否正确地子串本身 - 但是我在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 时,我在委托中遇到了一些错误的访问 -这没有任何意义(我实际上有一个完全空的表,等等...) - 所以我想我用我的子字符串进行了糟糕的内存管理,现在它在这个委托调用中遇到了麻烦。
Chuck,我对你的评论非常感兴趣,因为我被告知创建变量的正确方法是调用 [myclass alloc] init];然后在完成后释放——就像我一样。当然,我的 Objective-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 ——我发现这是让它们实际工作的唯一方法。
I'm attempting to complete the Stanford iPhone Programming (FA10) assignement "Flickr Fetcher" -- so far things are going well, however I have come to an impasse:
I have successfully extracted the location of the "Top 100" pictures, which are formated in a string as "Country, State, City". I would like to create two NSStrings -- one being the country, the other string being the State and City. From where I can then do
cell.textLabel.text = countryString;
cell.detailTextLabel.text = stateCityString;
in my table view datasource methods.
From research on stackoverflow and the Apple Documentaion, NSScanner seems to be my best bet -- here is what I have so far...
- (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);
}
}
I'm just trying to see if the string properly substrings itself -- however I am getting a "SIGBART" at the beggining of the while loop, the error is this:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0x8939eb0'
From all the documentation I have seen on NSScanner, it seems I have it set up properly, however, no matter what changes I do, it seems unable to even begin the loop.
What do I have to do to set up NSScanner properly, to avoid the "SIGABRT"? (for the record, i'm assuming "SIGABRT" is a segfault?). Thank you all for your time, you all are the best!
(Btw: I know this is not fully implemented yet for both country and state-city, i just want to get used to NSScanner, I will implement the rest once I get NSScanner under control)
EDIT 1: SosBorn! You are incredible! Thank you so much! So I have implemented this for my 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];
}
This worked like a complete charm BUT i'm having some bad access going on in the Delegate when trying to access self.window.rootViewController = self.viewController
-- this doesn't make any-sense (i actually have a completely empty table, etc...) -- so i'm thinking I played with bad memory management with my substring-ing and now it gets in trouble with this delegate call.
Chuck, I was very interested in your comment as I was taught that the proper way to make variables is to call [myclass alloc] init]; and then release when you are done -- as I have. Of course my objective-C greenness is showing a bit... blush.
You all and this incredible community are such an asset to us Students -- thank you for all your time and dedication. The only path to progress is a path of cooperation!
EDIT 2: Ok -- now it's totally fixed with no terrible leaking problems. Chuck you were right! I had the pricniples of alloc init completely mixed up in my head -- here was my final solution:
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");
}
Thank you again SosBorn, i was feeling like I had forgotten the basics of CS ಠ_ಠ.
The only thing that really bothers me is why do we have to initialize instance NSMutableArrays that way -- i found this was the only way to get them to actually work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不完全确定它崩溃的原因,但我认为另一种方法会更好地为您服务。您有一个 topPlacesArray,为什么不迭代该数组并单独处理每个数组条目?我对 topPlacesArray 做了一些假设,但它看起来像这样:
没有花时间处理内存管理,但你明白了。
Not totally sure why it is crashing, but I think another approach to this would serve you better. You have a topPlacesArray, why not iterate through the array and process each array entry seperately? I am making some assumptions about the topPlacesArray, but it would look something like this:
Didn't take the time to handle memory management but you get the idea.