Dear Nick and all,

Thanks so much for your reply! I am still a new Cocoa developer so that I
need to improve during the programming procedure.

Now I modify the code and it works fine. The code is as follows.

But I still have a question. If the autoreleased data will keep alive until
the pool is drained, what if the data is autoreleased in a Cocoa
auto-created pool? It will keep alive unless the process is shutdown?

Thanks!
Bing

- (NSString *) receiveMessage
{
        NSMutableString *receivedString;
        NSString *message;
        [isConnectedLock lock];
        @try
        {
                if (isConnected)
                {
                        char buffer[Constants.WWW.BUFFER_SIZE];
                        ssize_t numBytesReceived = recv(destinationSocket,
buffer, Constants.WWW.BUFFER_SIZE, 0);
                        if (numBytesReceived <= 0)
                        {
                                return Constants.WWW.NO_RECEIVED_MESSAGE;
                        }
                        buffer[numBytesReceived] = '\0';

                        receivedString = [[NSMutableString alloc]
initWithBytes:buffer length:numBytesReceived encoding:NSUTF8StringEncoding];

                        NSRange range = [receivedString
rangeOfString:Constants.WWW.DELIMITER];
                        if (range.location > 0 && range.location <
[receivedString length])
                        {
                                message = [receivedString
substringToIndex:range.location];
                                return message;
                        }
                        else
                        {
                                while (numBytesReceived > 0)
                                {
                                        NSAutoreleasePool *loopPool =
[[NSAutoreleasePool alloc] init];
                                        numBytesReceived =
recv(destinationSocket, buffer, Constants.WWW.BUFFER_SIZE, 0);
                                        if (numBytesReceived <= 0)
                                        {
                                                [loopPool drain];
                                                break;
                                        }
                                        buffer[numBytesReceived] = '\0';
                                        NSString *newReceivedString =
[[[NSString alloc] initWithBytes:buffer length:numBytesReceived
encoding:NSUTF8StringEn
coding] autorelease];
                                        [receivedString
appendString:newReceivedString];
                                        range = [receivedString
rangeOfString:Constants.WWW.DELIMITER];
                                        if (range.location > 0 &&
range.location < [receivedString length])
                                        {
                                                message = [receivedString
substringToIndex:range.location];
                                                [loopPool drain];
                                                break;
                                        }
                                        [loopPool drain];
                                }
                        }
                        return message;
                }
                else
                {
                        return Constants.WWW.NO_RECEIVED_MESSAGE;
                }
        }
        @catch (NSException *e)
        {
                NSLog(@"%@", e);
                return Constants.WWW.NO_RECEIVED_MESSAGE;
        }
        @finally
        {
                [isConnectedLock unlock];
                [receivedString autorelease];
        }
}


On Tue, May 31, 2011 at 11:13 AM, Nick Zitzmann <n...@chronosnet.com> wrote:

>
> On May 30, 2011, at 8:15 PM, Bing Li wrote:
>
> > - (NSString *) receiveMessage
> > {
> >        NSMutableString *receivedString;
> >        NSString *message;
> >        NSString *newReceivedString;
> >        [isConnectedLock lock];
> >        @try
> >        {
> >                if (isConnected)
> >                {
> >                        char buffer[Constants.WWW.BUFFER_SIZE];
> >
> >                        // Receive remote data
> >                        ssize_t numBytesReceived = recv(destinationSocket,
> > buffer, Constants.WWW.BUFFER_SIZE, 0);
> >                        if (numBytesReceived <= 0)
> >                        {
> >                                return Constants.WWW.NO_RECEIVED_MESSAGE;
> >                        }
> >                        buffer[numBytesReceived] = '\0';
> >
> >
> >                        // Convert data to NSString locally
> >                        receivedString = [[NSMutableString alloc]
> > initWithBytes:buffer length:numBytesReceived
> encoding:NSUTF8StringEncoding];
> >                        message = [[NSString alloc]
> > initWithString:Constants.WWW.EMPTY_STRING];
>
> Why are you storing a non-autoreleased object to a pointer and then writing
> over it later?
>
> >
> >
> >                        // Since the data has specific formats, some
> simple
> > parsing jobs by delimiter are done as follows.
> >
> >                        NSRange range = [receivedString
> > rangeOfString:Constants.WWW.DELIMITER];
> >                        if (range.location > 0 && range.location <
> > [receivedString length])
> >                        {
> >                                message = [receivedString
> > substringToIndex:range.location];
>
> Here you're overwriting a pointer to an object you own with an autoreleased
> object.
>
> >
> >                                // Return data after parsing
> >                                return message;
> >                        }
> >                        else
> >                        {
> >                                // Receive remote data continually if the
> > receivedString is longer than expected
> >                                while (numBytesReceived > 0)
> >                                {
> >                                        NSAutoreleasePool *loopPool =
> > [[NSAutoreleasePool alloc] init];
> >
> >                                        // Receive data
> >                                        numBytesReceived =
> > recv(destinationSocket, buffer, Constants.WWW.BUFFER_SIZE, 0);
> >                                        if (numBytesReceived <= 0)
> >                                        {
> >                                                return
> > Constants.WWW.NO_RECEIVED_MESSAGE;
>
> Here you're leaking the autorelease pool you created above.
>
> >                                        }
> >
> >
> >                                        buffer[numBytesReceived] = '\0';
> >                                        newReceivedString = [[[NSString
> > alloc] initWithBytes:buffer length:numBytesReceived
> > encoding:NSUTF8StringEncoding] autorelease];
> >                                        range = [receivedString
> > rangeOfString:Constants.WWW.DELIMITER];
> >                                        if (range.location > 0 &&
> > range.location < [receivedString length])
> >                                        {
> >                                                message = [receivedString
> > substringToIndex:range.location];
> >
> >                                                // Return data after
> parsing
> >                                                return message;
>
> Here you're placing a new object in the autorelease pool, and then leaking
> the autorelease pool.
>
> >                                        }
> >                                        [loopPool drain];
> >                                }
> >                        }
> >                        return Constants.WWW.NO_RECEIVED_MESSAGE;
> >                }
> >                else
> >                {
> >                        return Constants.WWW.NO_RECEIVED_MESSAGE;
> >                }
> >        }
> >        @catch (NSException *e)
> >        {
> >                return Constants.WWW.NO_RECEIVED_MESSAGE;
> >        }
> >        @finally
> >        {
> >                [isConnectedLock unlock];
> >
> >                // Before returning received data, autorelease them here.
> >                [receivedString autorelease];
> >                [message autorelease];
>
> Here you're autoreleasing a pointer that may or may not have been
> autoreleased already.
>
> I suggest you re-read the memory management rules again and pay attention
> to the rules regarding release and autorelease. If anyone tries to re-state
> it here, we're inevitably going to get something wrong.  <
> http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
> >
>
> Also, I cannot recommend writing an object to a pointer that the program is
> never going to read. If you're concerned about accidentally accessing an
> uninitialized pointer, then just set it to nil instead.
>
> Nick Zitzmann
> <http://www.chronosnet.com/>
>
>
>
>
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to