• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Memory not being freed
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Memory not being freed


  • Subject: Re: Memory not being freed
  • From: Mark Williams <email@hidden>
  • Date: Tue, 8 Nov 2005 08:55:56 -0700

Ok, last message was too large, let me try this again.
Here is the code for my stream. I think this is the problem but I'm not sure. It is based on the example stream test.


@interface AGDStreamObj : NSObject
{

	NSDictionary *agent;

	id streamDelegate;
	CFReadStreamRef readStream;
	CFWriteStreamRef writeStream;
	UInt8 *recvBuffer;
	NSMutableData *writeBuffer;
        NSMutableString *readBuffer;
        NSTimer * timer;
	float workUnitsExpected;
	float workUnitsCompleted;
	Byte theFlags;
	BOOL toFlag;
	int timeout;
}

- (id) initWithHostInfo: (NSDictionary *)anAgent delegate:(id)sender;
-(void)setTimeOut:(int)to; //Default is 60 seconds

- (BOOL) open;
- (void) close;

- (void) writeLine: (NSString *)aLine;
- (void) writeLineWithFormat: (NSString *)aFormat, ...;

@end

@interface NSObject (StreamDelegateMethods)

-(void)newBytesAvailable:(NSData*)newData;

-(void)streamDisconnected;
-(void)streamErrorOccured:(CFStreamError)error errorText:(NSString*) errTxt;
-(void)streamDisconnectWithError:(CFStreamError)error;
-(void)dataWritten:(NSString*)string;
-(void)streamConnected:(NSString*)connect;
-(void)streamTimedOut;
@end



/* Agent Dictionary Keys */

AGD_KEY NSString * const AGDServerAddress;
AGD_KEY NSString * const AGDServerPort;


#import "AGDStreamObj.h"

NSString * const AGDServerAddress = @"AGDServerAddress";
NSString * const AGDServerPort    = @"AGDServerPort";

@interface AGDStreamObj (Private)

- (void) streamHasBytesAvailable;
- (void) streamCanAcceptBytes;
- (void) streamOpenCompleted;
- (void) streamErrorOccurred;
-(void)closeWithError:(CFStreamError)err;

@end



@implementation AGDStreamObj


/***** * Object lifecycle *****/


- (id) initWithHostInfo: (NSDictionary *)anAgent delegate:(id)sender

{

if ((self = [super init]))
{
theFlags = 0x00;
recvBuffer = malloc(8192);
toFlag = NO;
timeout = 60.0;
streamDelegate = sender;
agent = [[NSDictionary alloc] initWithDictionary:anAgent];


if(![sender respondsToSelector:@selector(newBytesAvailable:)]){
NSLog(@"Illegal Stream delegate. StreamObj Delegates must implement:\nnewBytesAvailable:\nstreamDisconnected \nstreamErrorOccured:\nstreamDisconnectWithError:\nstreamConnected:\n");
}
if(![sender respondsToSelector:@selector (streamErrorOccured:errorText:)]
|| ![sender respondsToSelector:@selector (streamConnected:)]){
//Not a legal delegate
NSLog(@"Illegal Stream delegate. StreamObj Delegates must implement:\nnewBytesAvailable:\nstreamDisconnected \nstreamErrorOccured:\nstreamDisconnectWithError:\nstreamConnected:\n");
}
if(![sender respondsToSelector:@selector (streamDisconnectWithError:)] && ![sender respondsToSelector:@selector (streamDisconnected)]){ //Not a legal delegate
NSLog(@"Illegal Stream delegate. StreamObj Delegates must implement:\nnewBytesAvailable:\nstreamDisconnected \nstreamErrorOccured:\nstreamDisconnectWithError:\nstreamConnected:\n");
}
}
return self;


}

-(void)setTimeOut:(int)to
{
    timeout = to;
}

- (void) dealloc

{
    [self close];
	free(recvBuffer);
	free(writeStream);
	free(readStream);
	[writeBuffer release];
	[readBuffer release];
    [super dealloc];
}


void readStreamCallBack(CFReadStreamRef stream, CFStreamEventType type, void *transportStream)
{
id self = (id)transportStream;
switch (type)
{
case kCFStreamEventHasBytesAvailable:
{
[self streamHasBytesAvailable];
break;
}
case kCFStreamEventOpenCompleted:
{
[self streamOpenCompleted];
break;
}
default:
case kCFStreamEventErrorOccurred:
{
[self streamErrorOccurred];
break;
}
}
}




void writeStreamCallBack(CFWriteStreamRef stream, CFStreamEventType type, void *transportStream)
{
id self = (id)transportStream;
switch (type)
{
case kCFStreamEventCanAcceptBytes:
{
[self streamCanAcceptBytes];
break;
}
default:
case kCFStreamEventErrorOccurred:
{
[self streamErrorOccurred];
break;
}
}
}


-(void)requestTimeOut:(id)sender
{
if(toFlag){
if([streamDelegate respondsToSelector:@selector (stramTimedOut)]) [streamDelegate performSelector:@selector (streamTimedOut)];
[self close];
}
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
toFlag = NO;
}


- (BOOL) open
/*
Opens the connection.
*/
{
CFStreamStatus readStreamStatus;
CFStreamStatus writeStreamStatus;
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
NSDate * theDate = [[NSDate alloc] initWithTimeIntervalSinceNow:timeout];
timer = [[NSTimer alloc]initWithFireDate:theDate interval:timeout
target:self selector:@selector (requestTimeOut:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
toFlag = YES;


if (!readStream)
{
// create our streams
CFStreamClientContext clientContext =
{
NULL,
(void *)self,
(void *(*)(void *))CFRetain,
(void(*)(void *))CFRelease,
(CFStringRef(*)(void*))CFCopyDescription
};
CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)[agent objectForKey:AGDServerAddress],[[agent objectForKey:AGDServerPort] intValue], &readStream, &writeStream);
CFReadStreamSetClient(readStream,
kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventOpenCompleted | kCFStreamEventEndEncountered,
&readStreamCallBack,
&clientContext);
CFWriteStreamSetClient(writeStream,
kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred,
&writeStreamCallBack,
&clientContext);
CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent (), kCFRunLoopCommonModes);
}

readStreamStatus = CFReadStreamGetStatus(readStream);
writeStreamStatus = CFWriteStreamGetStatus(writeStream);


	if ((kCFStreamStatusNotOpen == readStreamStatus) ||
		(kCFStreamStatusNotOpen == writeStreamStatus))
	{
		CFReadStreamOpen(readStream);
		CFWriteStreamOpen(writeStream);
		return NO;
	}

	return YES;

}


- (void) close
/*
Shuts down the socket, closes the socket, prevents any furthering monitoring of activity on that socket and discards any queued writes for that socket.
*/
{


	if (readStream)
	{
		CFReadStreamClose(readStream);
		CFRelease(readStream);
		readStream = NULL;
	}

	if (writeStream)
	{
		CFWriteStreamClose(writeStream);
		CFRelease(writeStream);
		writeStream = NULL;
	}

    // flush the write and read buffers
	[writeBuffer release];
	writeBuffer = nil;
        [readBuffer release];
	readBuffer = nil;
        [streamDelegate performSelector:@selector(streamDisconnected)];

}




- (void) writeLine: (NSString *)aLine
/*
Writes the specified line when we can.
*/
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
NSDate * theDate = [[NSDate alloc] initWithTimeIntervalSinceNow:timeout];
timer = [[NSTimer alloc]initWithFireDate:theDate interval:timeout
target:self selector:@selector (requestTimeOut:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
toFlag = YES;


if (!writeBuffer)
{
writeBuffer = [[NSMutableData alloc] init];
}
[writeBuffer appendData: [aLine dataUsingEncoding: NSUTF8StringEncoding]];
[writeBuffer appendData: [@"\r\n" dataUsingEncoding: NSUTF8StringEncoding]];
[streamDelegate dataWritten:aLine];
[self streamCanAcceptBytes];

}
- (void) writeLineWithFormat: (NSString *)aFormat, ...
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(requestTimeOut:) object:nil];
[timer invalidate];
[timer release];
NSDate * theDate = [[NSDate alloc] initWithTimeIntervalSinceNow:timeout];
timer = [[NSTimer alloc]initWithFireDate:theDate interval:timeout
target:self selector:@selector (requestTimeOut:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
toFlag = YES;


    va_list argList;
    NSString *formattedString;

va_start(argList, aFormat);
formattedString = [[NSString alloc] initWithFormat: aFormat arguments: argList];
va_end(argList);
[self writeLine: formattedString];
[formattedString release];
}




/*****
* Generic/errror handling
*****/


- (void) handleGenericResponseLine: (NSString *)aLine
/*
Processes any response which has not yet been handled... this is generally either a request for authorization or a generic error message.
*/
{
if ([aLine length]) [streamDelegate performSelector:@selector (newDataAvailable:) withObject:aLine];
}


@end

@implementation AGDStreamObj (Private)

- (void) streamHasBytesAvailable
/*
Private method - gets called when the read stream is ready to be read from.
*/
{


	CFIndex length = CFReadStreamRead(readStream, recvBuffer, 8192);

if (length >=0)
{
toFlag = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector (requestTimeOut:) object:nil];
NSData *data = [NSData dataWithBytes: recvBuffer length: length];


[streamDelegate performSelectorOnMainThread:@selector (newBytesAvailable:) withObject:data waitUntilDone:YES];
}
}



- (void) streamCanAcceptBytes
/*
Private method - gets called when the write stream is ready to be written to.
*/
{


if ([writeBuffer length] && CFWriteStreamCanAcceptBytes(writeStream))
{
CFIndex length = CFWriteStreamWrite(writeStream, [writeBuffer bytes], [writeBuffer length]);
if (length = [writeBuffer length])
{
[writeBuffer release];
writeBuffer = nil;
}
else
{
[writeBuffer replaceBytesInRange: NSMakeRange(0, length) withBytes: NULL];
}
}

}



- (void) streamOpenCompleted
/*
Private method - gets called when the stream is open
*/
{
NSString * con = [NSString stringWithFormat:@"Connected To: % @ on Port: %@",[agent objectForKey:AGDServerAddress],[agent objectForKey:AGDServerPort]];
[streamDelegate performSelector:@selector(streamConnected:) withObject:con];
workUnitsCompleted = 0;
}



- (void) streamErrorOccurred
/*
Private method - gets called when there is a stream error
*/
{
CFIndex length = CFReadStreamRead(readStream, recvBuffer, 8192);
NSString *string =@"Unknown Error";
if (length != -1)
{

NSData *data = [NSData dataWithBytes: recvBuffer length: length];
string = [[NSString alloc] initWithData: data encoding: NSISOLatin1StringEncoding];
}
CFStreamError err = CFReadStreamGetError(readStream);
if(err.domain==1) [self closeWithError:err];
else if(CFReadStreamGetStatus(readStream) == kCFStreamStatusNotOpen) [self closeWithError:err];
else if(CFReadStreamGetStatus(readStream) == kCFStreamStatusAtEnd) [streamDelegate streamDisconnected];
else [streamDelegate streamErrorOccured:err errorText:string];
}


-(void)closeWithError:(CFStreamError)err
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(requestTimeOut:) object:nil];
[streamDelegate streamDisconnectWithError:err];
[self close];
}



@end

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Memory not being freed
      • From: Frederick Cheung <email@hidden>
References: 
 >Memory not being freed (From: Mark Williams <email@hidden>)
 >Re: Memory not being freed (From: John Stiles <email@hidden>)

  • Prev by Date: Re: Problems with NSURLConnection and NSString
  • Next by Date: Autoresizing pictures to make them fit in NSTextView
  • Previous by thread: Re: Memory not being freed
  • Next by thread: Re: Memory not being freed
  • Index(es):
    • Date
    • Thread