我正在努力教自己客观-c。我曾经(~10年前)用c ++很好,所以我认为这不应该太难,但是经过这么多年的python和各种数学编程语言,我在指针上很生锈,我认为是可能是造成这种情况的原因。
无论如何,对于文档和xcode的调试输出中肯定存在的方法(我不是很熟悉,所以这可能是错误的),我一直得到无法识别的选择器错误,这表明这些对象已初始化。我试图尽可能小地制作以下示例。这是我写的课程:
// Graph.h
#import <Foundation/Foundation.h>
@interface Graph : NSObject
@property NSMutableSet *myObjects;
- (id)initWithNumElements:(int)total;
- (NSMutableSet *)addOneMore:(NSMutableSet *)vertices;
- (NSMutableSet *)addTo:(NSMutableSet *)R from:(NSMutableSet *)P;
@end
它的实施:
// Graph.m
#import "Graph.h"
@implementation Graph
// Put numbers 0, ..., total - 1 into the objects of self
- (id)initWithNumElements:(int)total {
self = [super init];
if (self) {
NSMutableSet *objects = [[NSMutableSet alloc] init];
for (int i=0; i<total; i++) {
[objects addObject:[NSNumber numberWithInt:i]];
}
_myObjects = objects;
}
return self;
}
// If possible, add one of the objects of self to set
- (NSMutableSet *)addOneMore:(NSMutableSet *)set {
NSMutableSet *allObjects = [self.myObjects copy];
for (id elt in set) {
[allObjects removeObject:elt];
}
//[allObjects minusSet:set];
return [self addTo:[set copy] from:allObjects];
}
// If possible, add one object from P to R
- (NSMutableSet *)addTo:(NSMutableSet *)R from:(NSMutableSet *)P {
if ([P count] == 0) {
return R;
}
id v = [P anyObject];
[R addObject:v];
return R;
}
@end
我正在使用以下代码对其进行测试:
// main.m
#import <Foundation/Foundation.h>
#import "Graph.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Graph *G = [[Graph alloc] initWithNumElements:6];
NSMutableSet *results = [G addOneMore:[[NSMutableSet alloc] init]];
NSLog(@"%@", results);
}
return 0;
}
(我从逻辑上知道这段代码没有任何意义。它简化为曾经只有少量意义的东西的愚蠢。)
我收到错误
2014-10-27 11:19:14.936 Test[1469:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSetI addObject:]: unrecognized selector sent to instance 0x100108a20'
和xcode完全指向“[R addObject:v];”行。但调试的东西说R是NSMutableSet *而v是_NFCSNumber *所以问题是什么?据我所知,这应该是有效的。
注释掉的行“// [allObjects minusSet:set];”也产生了一个无法识别的选择器错误,当我用它上面的for循环替换它时不会发生。就我所见,这条线应该是有效的,我无法弄清楚这里有什么问题。
答案 0 :(得分:7)
在addOneMore:
中,
NSMutableSet *allObjects = [self.myObjects copy];
不会将可变集分配给allObjects
,而是赋予不可变NSSet
。如果你想要一个可变副本,你需要使用mutableCopy
,即使源容器(set,array,dictionary)是一个可变的变体。 copy
返回不可变实例。
您收到无法识别的选择器错误,因为addObject:
不是不可变集的有效选择器。