Objective c 子类化NSStream

Objective c 子类化NSStream,objective-c,ios,cocoa-touch,Objective C,Ios,Cocoa Touch,我试图将NSInputStream和NSOutputStream子类化,以跟踪传递给服务器的命令。这样,当我收到来自服务器的响应时,我就知道它是对哪个命令的响应。当我试图在我的子类中设置命令字符串时,我得到一个无法识别的选择器错误 子类: PCFInputStream.h #import <Foundation/Foundation.h> @interface PCFInputStream : NSInputStream @property (nonatomic, strong)

我试图将NSInputStream和NSOutputStream子类化,以跟踪传递给服务器的命令。这样,当我收到来自服务器的响应时,我就知道它是对哪个命令的响应。当我试图在我的子类中设置命令字符串时,我得到一个无法识别的选择器错误

子类:

PCFInputStream.h

#import <Foundation/Foundation.h>

@interface PCFInputStream : NSInputStream
@property (nonatomic, strong) NSString *command;
@end
#import <Foundation/Foundation.h>

@interface PCFOutputStream : NSOutputStream
@property (nonatomic, strong) NSString *command;
@end
这是我在运行该行时得到的错误

[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*命令包装到另一个类中,但这不符合我的目的


谢谢

CFStreamCreatePairWithSocketToHost
创建
CFWriteStream
CFReadStream
。它们分别与
NSOutputStream
NSInputStream
免费桥接。因此,您得到的是一个
NSOutputStream
和一个
NSInputStream
。不管你是否声明了它们的子类,都没有区别;这些是
CFStreamCreatePairWithSocketToHost
创建的类


如果您真的无法使用包装,不管怎样,您需要重新实现核心基础函数来创建自定义子类。实际上,我建议您只包装

NS[Output/Input]流
并使用
forwardingTargetForSelector:
,这样您就可以在任何可以接受原始对象的地方提供包装器。

CFStreamCreatePairWithSocketToHost
创建
CFWriteStream
CFReadStream
。它们分别与
NSOutputStream
NSInputStream
免费桥接。因此,您得到的是一个
NSOutputStream
和一个
NSInputStream
。不管你是否声明了它们的子类,都没有区别;这些是
CFStreamCreatePairWithSocketToHost
创建的类


如果您真的无法使用包装,不管怎样,您需要重新实现核心基础函数来创建自定义子类。实际上,我建议您只包装

NS[Output/Input]流
,并使用
forwardingTargetForSelector:
,这样您就可以在任何可以接受原始对象的地方提供包装器。

您不能将
NSInputStream
强制转换为
pcFinInputStream
。必须将该对象创建为
PCFInputStream
,而
CFStreamCReatePairWithSocketToHost
不会这样做

您只需使用一个属性将
命令
属性附加到类别中的
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
#导入
@实现NSInputStream(PCFCommand)
静态int-kpccommandkey;
-(NSString*)pcf_命令{
返回objc_getAssociatedObject(self和kPCFCommandKey);
}
-(void)setPcf_命令:(NSString*)pcf_命令{
objc_setAssociatedObject(self,&kPCFCommandKey,[pcf_命令副本],
OBJC(非原子的);
}
@结束

您不能将
NSInputStream
强制转换为
PCFInputStream
。必须将该对象创建为
PCFInputStream
,而
CFStreamCReatePairWithSocketToHost
不会这样做

您只需使用一个属性将
命令
属性附加到类别中的
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
#导入
@实现NSInputStream(PCFCommand)
静态int-kpccommandkey;
-(NSString*)pcf_命令{
返回objc_getAssociatedObject(self和kPCFCommandKey);
}
-(void)setPcf_命令:(NSString*)pcf_命令{
objc_setAssociatedObject(self,&kPCFCommandKey,[pcf_命令副本],
OBJC(非原子的);
}
@结束

我可能错误地包装了这些类。你介意给我举个简单的例子吗?我最初将它们包装在NSObject中我无法使包装器正常工作,但是如果我将它们包装在委托方法handleEvent中,我如何获得流发送的命令..因为handleEvent委托方法提供了一个NSStream对象,而不是包含string命令的自定义对象。我可能没有正确包装类。你介意给我举个简单的例子吗?我最初将它们包装在NSObject中我无法让包装器工作,但是如果我确实包装了它们,在委托方法handleEvent中,我如何获得流发送的命令..因为handleEvent委托方法提供了一个NSStream对象,而不是包含string命令的自定义对象。您好,您的示例非常有用。我只是不知道该把这个声明放在哪里。我以前从未使用过类别。请从菜单栏中选择“新建”>“文件”。然后从Cocoa Touch模板中选择Objective-C类别。将类别命名为
PCFCommand
,并将其设置为
NSInputStream
上的类别。您需要在要访问属性的任何文件中导入
NSInputStream+PCFCommand.h
。对
NSOutputStream
重复上述步骤。完美。我刚在你打字的时候发现了这个。找不到方法“objc_getAssociatedObject”。此外,常量“OBJC_关联_保留_非原子”也不起作用。我已经编辑了我的答案。你需要导入
。哈哈,你的评论和我要说的完全一样,没关系。哈哈,谢谢!嗨,你的例子很有帮助。我只是不知道该把这个声明放在哪里。我以前从未使用过类别。请从菜单栏中选择“新建”>“文件”。然后从Cocoa Touch模板中选择Objective-C类别。将类别命名为
PCFCommand
,并将其设置为
NSInputStream
上的类别。您需要在要访问属性的任何文件中导入
NSInputStream+PCFCommand.h
。对
NSOutputStream
重复上述步骤。完美。我刚在你打字的时候发现了这个。找不到方法“objc_getAssociatedObject”。还有c