- [Person componentsSeparatedByString:]:无法识别的选择器发送到实例

时间:2014-12-27 23:54:08

标签: ios objective-c nsstring nsmutablearray nsobject

我是编程新手,我觉得有点吓人的帖子,而且我被卡住了。我不想快速修复!请帮我理解这一点。

我创建了一个名称,年龄,身高和性别的自定义方法。当NSMutableArray将自定义对象添加到数组时,它会被调用。出于某种原因,我无法将所述项目从NSMutableArray中拉出来。让我们说年龄需要打印出来。我得到一个错误说...

-[Person componentsSeparatedByString:]:无法识别的选择器已发送到实例

Person.m

- (id)initWithName:(NSString *)n
            age:(int)a
         height:(float)h
         gender:(char)g
{
self = [super init];
if (self) {
    self.name = n;
    self.age = a;
    self.height = h;
    self.gender = g;
}

    return self;
}

- (NSString *)description
{
NSString *descriptionString = [[NSString alloc] initWithFormat:@"%@, %d, %.1f, %c",
                               self.name,
                               self.age,
                               self.height,
                               self.gender];
NSLog(@"Description String: %@", descriptionString);
    return descriptionString;
}

将对象添加到NSMutableArray时,它们会转换为NSString吗?如何在NSLog中没有整个字符串名称和高度的情况下让人们年龄?

ViewController.m

[self.people addObject:[[Person alloc] initWithName:@"Jake" age:29 height:73.5 gender:'f']];
[self.people addObject:[[Person alloc] initWithName:@"Jerry" age:24 height:82.3 gender:'m']];
[self.people addObject:[[Person alloc] initWithName:@"Jessica" age:29 height:67.2 gender:'f']];

NSString *mystring1 = [self.people objectAtIndex:0];
NSLog(@"%@", mystring1);

// Works
//NSString *list = @"Norm, 42, 73.2, m";

NSArray *listItems = [self.people[0] componentsSeparatedByString:@", "];
NSLog(@"List Items: %@", listItems[1]);// age

输出

Description String: Jake, 29, 73.5, f
Jake, 29, 73.5, f
-[Person componentsSeparatedByString:]: unrecognized selector sent to instance

解决:

注意额外的[年龄];

int age = [[self.people objectAtIndex:0]age];
NSLog(@"%d", age);

5 个答案:

答案 0 :(得分:1)

您无法在componentsSeparatedByString对象上执行Person,因为它不是字符串且没有该方法。 (NSMutableArray个对象会自动转换为NSString s。)但要获得Person的年龄,无论如何都应该相当简单。只需访问Person的{​​{1}}媒体资源:

age

修改:您可以在int age = self.people[0].age; NSLog(@"Age: %d", age); componentsSeparatedByString上技术上使用mystring1,如下所示:

NSString

但是,当您可以直接访问NSArray *listItems = [mystring1 componentsSeparatedByString:@", "]; NSLog(@"List Items: %@", listItems[1]);// age 的{​​{1}}媒体资源时,我认为没有这样做。

答案 1 :(得分:1)

componentsSeparatedByString方法是NSString类的实例方法。您无法以这种方式在Person课程上调用它。

如果您尝试访问年龄,我不知道您为什么需要该代码,那么:

NSLog(@"Age %d", self.people[0].age);

就够了。如果你想要实现任何其他的东西,那么你可以获得如下组件:

NSArray *listItems = [self.people[0].description componentsSeparatedByString:@", "];
NSLog(@"List Items: %@", listItems[1]);// age

答案 2 :(得分:1)

我认为您的对象似乎转换为字符串的原因是这一行,

NSString *mystring1 = [self.people objectAtIndex:0];

如果您要打印所有内容,则需要指定属性

NSString *nameString = [[self.people objectAtIndex:0]name];

答案 3 :(得分:0)

有人会认为这会起作用;但是,我不能在我的阵列上打电话给.age。

NSLog(@"Age %d", self.people[0].age);

提供以下输出......

Property 'age' not found on object of type 'id'

人们也会认为componentsSeparatedByString会起作用。它不会用逗号分隔我的字符串并给出错误。

-[Person componentsSeparatedByString:]: unrecognized selector sent to instance

已解决已阅读

答案 4 :(得分:0)

我认为您对为什么在记录对象时遇到字符串感到困惑,但是您无法对其执行任何方法。

这就是为什么你认为你得到一个字符串,你已经实现了来自NSObject protocoldescription属性。当您使用%@参数记录对象时,您将获得此属性的结果,该属性是一个字符串。

所以看看你的代码:

NSString *mystring1 = [self.people objectAtIndex:0]; //1
NSLog(@"%@", mystring1);                             //2

首先,你要从数组中获取第一个对象。 objectAtIndex返回id,它是指向NSObject的指针。这不是一个强类型的回报。您将它分配给错误的NSString,因为它实际上是一个人物对象。但由于您没有在其上调用任何NSString方法,因此编译器不会标记此错误的赋值。

第二件事是你只是得到description财产的结果,正如我已经提到的那样。

您编辑的解决方案:

int age = [[self.people objectAtIndex:0]age];

有效,但原因如下:您获得的objectAtIndex:0返回id。然后你发送消息age。 Objective-C是一种动态语言,这意味着您可以将任何消息发送到任何对象(尽管如果对象没有实现该方法,您会遇到运行时崩溃)在这种情况下,您的Person对象确实实现了{{1}方法(因为它是一个公共财产)所以你得到了一个年龄。

另一种做法:

age

为什么我这样做?

首先,我从数组中获取firstObject并将其放入一个类型变量中。这更安全,好像索引0处没有对象(即数组为空),那么您不会让应用程序崩溃。 NSInteger age; Person *person = self.people.firstObject; if (person) { age = person.age; } else { age = NSNotFound; } 会在firstObject上返回第一个对象(如果存在),如果它不存在的话。

其次,只有从数组中正确提取了人物,才能将年龄分配给nil变量。您应该更喜欢NSInteger超过NSInteger(以及int超过CGFloat)的特定类型,因为它们在32位或64位运行时将使用正确大小的变量`systems。

第三,如果无法创建人员,我会为该年龄分配float的值。这是一个非常大数字的typedef,可以与之比较。只是在年龄时返回0并不足以告诉你有错误。此人可以年龄为0.使用此代码,您可以使用以下代码测试年龄:

NSNotFound

这有多大意义吗?并不是的。当您开始编写真实的复杂应用程序时,这种防御性编程将自然而然地呈现给您。数组可以是空的,您的数据可能会被错误地创建,等等。编写优雅地处理这些可能性的代码是编程的真正技能。不幸的是,它有点啰嗦,你在网上找到的大多数教程都向你展示了简单,快乐的道路。

我希望这可以让您更好地了解您的代码正在做什么,以及您在编写健壮的代码时可以做些什么。