是否可以在A类中创建对象的实例并从B类访问该对象的同一实例?我正在尝试使用NSInputStream和NSOutputStream开发一个创建TCP套接字的应用程序,并且需要多个类才能访问它。
谢谢你, Travis Elliott
修改
这是我正在使用的代码。它是一个处理套接字连接的程序。我基本上需要能够从appDelegate和View控制器与同一个套接字进行通信。以下是我根据您的帮助编写的代码。我使用appDelegate作为控件(在你的例子中为D),也许我不能这样做。 CommunicationHub是我需要从AppDelegate和ViewController控制同一个实例的类。
AppDelegate.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "CommunicationHub.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>{
ViewController *viewController;
CommunicationHub *cHub;
}
@property (strong, nonatomic) UIWindow *window;
@property (strong, retain) ViewController *viewController;
@property (strong, retain) CommunicationHub *cHub;
-(void)CreateInstances;
@end
AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
@implementation AppDelegate
@synthesize viewController;
@synthesize cHub;
@synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self CreateInstances];
// Override point for customization after application launch.
return YES;
}
-(void)CreateInstances{
NSLog(@"Inside CreateInstances");
CommunicationHub *cHub = [[CommunicationHub alloc] init];
viewController = [[ViewController alloc] init];
[viewController initWithcHub:cHub];
NSLog(@"ID of cHub in AppDelegate is %i", cHub);
}
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(@"Application Will Resign Active");
[cHub disconnect];
}
@end
ViewController.h
#import <UIKit/UIKit.h>
#import "CommunicationHub.h"
@interface ViewController : UIViewController
{
CommunicationHub *cHub;
}
@property (strong, nonatomic) IBOutlet UITextField *IPAddress;
@property (strong, nonatomic) IBOutlet UITextField *PortNumber;
- (IBAction)goAwayKeyBoard:(id)sender;
- (IBAction)touchBackground:(id)sender;
-(void) initWithcHub:(CommunicationHub *)ptr;
- (IBAction)connectSocket:(id)sender;
- (IBAction)disconnectSocket:(id)sender;
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize IPAddress;
@synthesize PortNumber;
-(void) initWithcHub:(CommunicationHub *)ptr
{
cHub = [[ptr retain]init];
NSLog(@"id of cHub in ViewController is %i", cHub);
}
- (IBAction)connectSocket:(id)sender
{
//Called by button on UI.
int portNumber = [PortNumber.text intValue];
[cHub Connect:(int *)portNumber ipAddress:(IPAddress.text)];
}
- (IBAction)disconnectSocket:(id)sender
{
//Called by button on UI.
[cHub disconnect];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setIPAddress:nil];
[self setPortNumber:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
-(IBAction)goAwayKeyBoard:(id)sender{
[self resignFirstResponder];
}
- (IBAction)touchBackground:(id)sender {
[IPAddress resignFirstResponder];
[PortNumber resignFirstResponder];
}
@end
CommunicationHub.h
#import <UIKit/UIKit.h>
NSInputStream *inputStream;
NSOutputStream *outputStream;
@interface CommunicationHub : NSObject <NSStreamDelegate>
- (void)Connect:(int *)port ipAddress:(NSString *)ipAddress;
- (void) disconnect;
@end
CommunicationHub.m
#import "CommunicationHub.h"
@implementation CommunicationHub
- (void)Connect:(int *)port ipAddress:(NSString *)ipAddress
{
NSLog(@"inside connect method");
if ([inputStream streamStatus] == 0 ||[inputStream streamStatus] == 5 ||[inputStream streamStatus] == 6 ||[inputStream streamStatus] == 7)
{
NSString *myString = ipAddress;
CFStringRef *myCFString = (__bridge CFStringRef)myString;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, myCFString, port, &readStream, &writeStream);
inputStream = (__bridge NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
}
- (void) disconnect
{
NSLog(@"inside disconnect method");
if (inputStream != nil) {
if ([inputStream streamStatus] == 2) {
NSLog(@"Disconnecting Streams");
[inputStream close];
[outputStream close];
}else {
NSLog(@"Stream is not Open");
int status = [inputStream streamStatus];
NSLog(@"Stream Status is %i", status);
}
}else {
NSLog(@"Input Stream equals Nil");
}
}
@end
答案 0 :(得分:0)
使它变长: 假设你有A,B和C类。
需要从A和B访问C语言。 现在,让我们假设我们有控制器D,它实例化A和B. 让D首先实例化C,并将其存储在变量中。C *C_Class = [[[C alloc] init] autorelease];
接下来,用C实例化A和B(我假设'保留属性'在这里)
self.A_Class = [[[A alloc] initWithC:C_Class] autorelease];
self.B_Class = [[[B alloc] initWithC:C_Class] autorelease];
在这两个类中,您需要实例方法:
- (id)initWithC:(C *)C_Class;
并在.m文件中:
- (id)initWithC:(C *)C_Class {
C_C = [C_Class retain]; //Assuming a regular instance variable
}
- (void) dealloc {
[C_C release]; //All that is retained, must be released.
}
从现在开始,您可以通过名称“C_C”访问A类和B类中的一个C类实例。
现在,请注意,这只是从我的脑后写的,容易出错,但它应该没问题。
我希望它有所帮助:)
编辑:由于OP似乎遇到了这些代码片段的问题,我将添加更完整的代码。
让我们从控件类'D'开始。
D.h:
#import "A.h"
#import "B.h"
@interface D : NSObject
-(void)CreateInstances;
@property (strong, retain) A *A_Class;
@property (strong, retain) B *B_Class;
@end
D.M:
#import "D.h"
#import "C.h"
@implementation D
-(void)CreateInstances {
C *C_Class = [[C alloc] init] autorelease];
self.A_Class = [[[A alloc] initWithC:C_Class] autorelease];
self.B_Class = [[[B alloc] initWithC:C_Class] autorelease];
}
@end
A.h(B.h反映了这种行为,可能考虑为两者使用超类)
#import "C.h"
@interface A : NSObject {
C *C_Class; //Class Reference to the C-Object
}
-(id) initWithC:(C *)ptr; //Initialization method, which takes a 'C'-Object.
@end;
A.M
#import "A.h"
@implementation A
- (id) initWithC:(C *)ptr {
C_Class = [ptr retain]; //So the object doesn't get released prematurely.
}
- (void) dealloc {
[C_Class release]; //To avoid memory leaks.
}
@end
现在,请记住,我把它写在了我的头顶并且没有通过编译器运行它,但它应该工作,除了拼写错误等。
另一个编辑: 在OP添加了自己的代码后,我将在此处发布相关的“已更正”代码。
AppDelegate.m
-(void)CreateInstances{
NSLog(@"Inside CreateInstances");
cHub = [[CommunicationHub alloc] init]; //We're using the instance variable. Not the local one.
viewController = [[ViewController alloc] initWithcHub:cHub];
//[viewController initWithcHub:cHub]; //You may want to rethink your function names.
NSLog(@"ID of cHub in AppDelegate is %i", cHub);
}
ViewController.m
//If a method names STARTS with 'init', it SHOULD initialize the object.
-(id) initWithcHub:(CommunicationHub *)ptr
{
self = [super init]; //Calls the 'init' from the parent class.
if(self) {
cHub = [ptr retain]; //Just retain. After all, the object IS initialized already.
NSLog(@"id of cHub in ViewController is %i", cHub);
}
return self;
}
- (void) dealloc {
[cHub release]; //Basic rule of memory management: ALL that is retained, must be released. In dealloc, at latest.
}
- (IBAction)connectSocket:(id)sender
{
//Called by button on UI.
//Do not pass a pointer to anything, unless you mean to use a pointer.
[cHub Connect:[PortNumber.text intValue] ipAddress:(IPAddress.text)];
}
其余部分应该是正确的,或者至少不是这个问题的主题。