【问题标题】:unrecognized selector sent to instance while trying to add an object to a mutable array尝试将对象添加到可变数组时发送到实例的无法识别的选择器
【发布时间】:2012-11-25 23:01:04
【问题描述】:

我正在关注“Your Second iOS App”,我决定使用代码来更好地理解 Objective C...

我想要做的只是将一个对象添加到类中的可变数组中。以下是课程:

BirdSighting.h

#import <Foundation/Foundation.h>

@interface BirdSighting : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *location;
@property (nonatomic, copy) NSDate *date;

-(id) initWithName: (NSString *) name location:(NSString *) location date:(NSDate *) date;
@end

BirdSighting.m

#import "BirdSighting.h"

@implementation BirdSighting
-(id) initWithName:(NSString *)name location:(NSString *)location date:(NSDate *)date
{
    self = [super init];

    if(self) {
        _name = name;
        _location = location;
        _date = date;

        return self;
    }

    return nil;
}

@end

BirdSightingDataController.h

#import <Foundation/Foundation.h>
@class BirdSighting;

@interface BirdSightingDataController : NSObject
@property (nonatomic, copy) NSMutableArray *masterBirdSightingList;

- (NSUInteger) countOfList;
- (BirdSighting *) objectInListAtIndex: (NSUInteger) theIndex;
- (void) addBirdSightingWithSighting: (BirdSighting *) sighting;
@end

BirdSightingDataController.m

#import "BirdSightingDataController.h"

@implementation BirdSightingDataController
- (id) init {
    if(self = [super init]) {
        NSMutableArray *sightingList = [[NSMutableArray alloc] init];
        self.masterBirdSightingList = sightingList;
        return self;
    }

    return nil;
}

-(NSUInteger) countOfList 
{
    return [self.masterBirdSightingList count];
}

- (BirdSighting *) objectInListAtIndex: (NSUInteger) theIndex
{
    return [self.masterBirdSightingList objectAtIndex:theIndex];
}

- (void) addBirdSightingWithSighting: (BirdSighting *) sighting
{
    [self.masterBirdSightingList addObject:sighting];
}
@end

这就是我尝试将 BirdSighting 实例添加到可变数组的地方:

#import "BirdsMasterViewController.h"
#import "BirdsDetailViewController.h"

#import "BirdSightingDataController.h"
#import "BirdSighting.h"

@implementation BirdsMasterViewController

- (void)awakeFromNib
{
    [super awakeFromNib];

    BirdSightingDataController *dataController = [[BirdSightingDataController alloc] init];

    NSDate *date = [NSDate date];
    BirdSighting *sighting = [[[BirdSighting alloc] init] initWithName:@"Ebabil" location:@"Ankara" date: date];

    [dataController addBirdSightingWithSighting: sighting];
    NSLog(@"dataController: %@", dataController.masterBirdSightingList);

    self.dataController = dataController;

}
..........
@end

它在 BirdSightingDataController addBirdSightingWithSighting 方法中抛出 NSInvalidArgumentException...

我做错了什么?

这是完整的调试输出: 2012-11-26 01:22:38.495 BirdWatching[4597:c07]-[__NSArrayI addObject:]:无法识别的选择器发送到实例 0x71899d0 2012-11-26 01:22:38.496 BirdWatching[4597:c07] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSArrayI addObject:]:无法识别的选择器发送到实例 0x71899d0 '

【问题讨论】:

  • 其余的错误是什么?日志应提供有关无效参数异常的更多详细信息。我猜您正在尝试向数组添加 nil 引用。
  • 嗯,我用调试器检查了一下,它不是零。

标签: objective-c ios6


【解决方案1】:

这一行:

BirdSighting *sighting = [[[BirdSighting alloc] init] initWithName:@"Ebabil" location:@"Ankara" date: date];

应该是:

BirdSighting *sighting = [[BirdSighting alloc] initWithName:@"Ebabil" location:@"Ankara" date: date];

你不能调用两个初始化器。

更新:

根据完整的错误消息,我现在看到了问题。 NSMutableArray 您认为您拥有的属性实际上是 NSArray。这是由使用copy 定义属性引起的。

当您为属性定义copy 时,它会生成对象的不可变副本。因此,当您分配 NSMutableArray 时,会制作一个不可变副本,然后将其分配给实例变量。所以你最终分配了NSArray,而不是NSMutableArray

解决方法是从以下位置更改属性定义:

@property (nonatomic, copy) NSMutableArray *masterBirdSightingList;

到:

@property (nonatomic, strong) NSMutableArray *masterBirdSightingList;

【讨论】:

  • 我知道我错过了 smt。愚蠢的 :) 但是,在按照您的描述进行修复后,我仍然遇到同样的错误。
  • @HotLicks 我刚刚根据完整的错误消息更新了我的答案。
【解决方案2】:

如果您阅读错误消息,它会说“addObject”已“发送”到 NSArray,这是无效的。这是真的。如果您查看 NSArray 的规范,您将找不到方法“addObject”。

您有一个 NSArray 试图在其上执行“addObject”。很难说在哪里,因为您显然没有列出发生错误的代码部分,或者您在第一次将“masterBirdSightingList”设置为 NSArray 之后,首先将其设置为 NSMutableArray。

【讨论】:

  • 啊,正如 maddy 指出的那样,您将属性设置为“copy”,这会导致奇怪的行为。
  • 如果属性的类型明显是可变的,那么属性上的copy 的语义没有调整为mutableCopy,这很遗憾。
  • 是的,那个可能会烧死我。如果你没有提到它,就永远不会注意到它。 (但后来我发现copy 没有多大用处。)
  • 我前段时间从第一手经验中学到了这一点 :) 我很少使用带有可变类型属性的 copy,我编写了自己的 setter 来获得 mutableCopy 语义。
【解决方案3】:

0

我有类似的错误说:无法识别的选择器已发送到 NSMutable 数组的实例。在经历了很多事情之后,我发现我正在使用我的可变数组作为属性

@property (assign, nonatomic) NSMutableArray *myMutableArray;

复制粘贴时不注意,导致问题。

我将其更改为强类型的解决方案(您可以将其更改为任何其他类型,如强/弱等。根据您的要求)。所以我的解决方案是:

@property (strong, nonatomic) NSMutableArray *myMutableArray; 所以,复制粘贴时要小心!请检查一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2012-07-24
    相关资源
    最近更新 更多