我正在尝试对NSInputStream和NSOutputStream进行子类化,以跟踪我传递给服务器的命令。这样,当我收到来自服务器的响应时,我就知道它是对哪个命令的响应。当我试图在我的子类中设置命令字符串时,我得到一个无法识别的选择器错误。
子类:
PCFInputStream.h
#import <Foundation/Foundation.h>
@interface PCFInputStream : NSInputStream
@property (nonatomic, strong) NSString *command;
@endPCFOutputStream.h
#import <Foundation/Foundation.h>
@interface PCFOutputStream : NSOutputStream
@property (nonatomic, strong) NSString *command;
@end.m文件只合成了命令属性,所以我可以调用setCommand:
下面是我在其中使用的类:
//instance vars in my class
PCFInputStream *inputStream;
PCFOutputStream *outputStream;
-(void)followClass:(id)sender
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef) SERVER_ADDRESS, PORT, &readStream, &writeStream);
inputStream = (__bridge_transfer PCFInputStream *)readStream;
outputStream = (__bridge_transfer PCFOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setCommand:[NSString stringWithFormat:@"%d,%@",[sender tag], [class classTitle]]];
[inputStream open];
NSString *str = [NSString stringWithFormat:@"_ADD_CLASS*%@*%@*%@*%@;", [class CRN], deviceToken, [class classLink],[class courseNumber]];
[outputStream setCommand:str];
[outputStream open];
}下面是我在运行这行代码时得到的错误
[inputStream setCommand:[NSString stringWithFormat:@"%d,%@",[sender tag], [class classTitle]]];
-[__NSCFInputStream setCommand:]: unrecognized selector sent to instance 0x1e691170
2012-12-01 21:56:20.777 PCF[15610:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFInputStream setCommand:]: unrecognized selector sent to instance 0x1e691170'
*** First throw call stack:
(0x3a1b73e7 0x39043963 0x3a1baf31 0x3a1b964d 0x3a111208 0xfa267 0x39585047 0x39584ffb 0x39584fd5 0x3958488b 0x39584d79 0x394a3441 0x3a18c941 0x3a18ac39 0x3a18af93 0x3a0fe23d 0x3a0fe0c9 0x3743733b 0x394ee291 0x100005 0xe7d48)
libc++abi.dylib: terminate called throwing an exception有人能给我一个简单的解决方案吗?我尝试将一个NSStreamInput实例和我的NSString*命令包装到另一个类中,但这不符合我的目的。
谢谢!
发布于 2012-12-02 11:57:48
您不能简单地将NSInputStream转换为PCFInputStream。必须将对象创建为PCFInputStream,而CFStreamCReatePairWithSocketToHost不会这样做。
您只需使用associated object将command属性附加到类别中的NSInputStream。以下是类别接口:
@interface NSInputStream (PCFCommand)
@property (nonatomic) NSString *pcf_command;
@end您可以像这样实现它:
#import <objc/runtime.h>
@implementation NSInputStream (PCFCommand)
static int kPCFCommandKey;
- (NSString *)pcf_command {
return objc_getAssociatedObject(self, &kPCFCommandKey);
}
- (void)setPcf_command:(NSString *)pcf_command {
objc_setAssociatedObject(self, &kPCFCommandKey, [pcf_command copy],
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end发布于 2012-12-02 11:07:02
CFStreamCreatePairWithSocketToHost创建一个CFWriteStream和一个CFReadStream。它们分别与NSOutputStream和NSInputStream进行了免费桥接。所以你得到的是一个NSOutputStream和一个NSInputStream。无论您是否声明了这些类的子类,都没有区别;这些都是CFStreamCreatePairWithSocketToHost创建的类。
如果您真的因为某种原因不能使用包装,那么您将需要重新实现Core Foundation函数来创建自定义子类。在实践中,我建议您只包装NS[Output/Input]Stream并使用forwardingTargetForSelector:,这样您就可以在任何原始对象可接受的地方提供包装器。
https://stackoverflow.com/questions/13665983
复制相似问题