[ https://issues.apache.org/jira/browse/THRIFT-1264?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jake Farrell closed THRIFT-1264. -------------------------------- Resolution: Fixed Fix Version/s: 1.0 Committed, Thanks for the patch > TSocketClient is queried by run loop after deallocation in Cocoa > ---------------------------------------------------------------- > > Key: THRIFT-1264 > URL: https://issues.apache.org/jira/browse/THRIFT-1264 > Project: Thrift > Issue Type: Bug > Components: Cocoa - Library > Affects Versions: 0.7, 0.9 > Environment: iPad, iOS SDK 4.3, iOS SDK 5.1 > Reporter: Jan RĂ¼th > Priority: Critical > Fix For: 1.0, 0.9 > > Attachments: THRIFT-1264.diff, TSocketClient.m > > > When using TSocketClient in a Cocoa client and correctly managing the memory: > {code:title=Server.m|borderStyle=solid} > - (id)initWithServer:(NSString*)server port:(NSInteger)port > { > self = [super init]; > if (self) { > TSocketClient *transport = [[TSocketClient alloc] > initWithHostname:server > port:port]; > TBinaryProtocol *protocol = [[TBinaryProtocolFactory sharedFactory] > newProtocolOnTransport:transport]; > Client *client = [[Client alloc] initWithProtocol:protocol]; > // self.client is a retained property > self.client = client; > [client release]; > [protocol release]; > [transport release]; > } > > return self; > } > - (void)dealloc { > self.client = nil; > [super dealloc]; > } > {code} > (maybe this should be fixed in the cocoa example, memory management is > erroneous there) > After successfully releasing the object with the code above. One gets a > EXC_BAD_ACCESS signal because the runloop send a responseToSelector: message > to our object. With the selector stream:handleEvent: > This all leads to TSocketClient which opens two NSStream objects and > delegates it self to both, afterwards both Streams are scheduled in the > runloop, which should actually notify the delegate when something happens to > the stream like data is available, this obviously results in the runloop > asking TSocketClient for previously described selector. However this > mechanism is not used, the TNSStreamTransport class is subclassed and > responsible for read/write. > So why are the Streams schedules in the run loop in the first place? > Why are the streams not closed and released when the object gets deallocated? > I could fix this behavior by implementing a dealloc method in TSocketClient > and making the Streams member variables > {code:title=TSocketClient.h|borderStyle=solid} > @interface TSocketClient : TNSStreamTransport { > NSInputStream * inputStream; > NSOutputStream * outputStream; > } > {code} > {code:title=TSocketClient.m|borderStyle=solid} > -(void)dealloc { > [inputStream close]; > [outputStream close]; > [inputStream release]; > [outputStream release]; > [super dealloc]; > } > {code} > However I still don't know if that is the right way. > Suggestions? > Edit: > The bug is still present in 0.9 I attached a TSocketClient.m that fixes this > Problem, the TSocketClient also keeps track of the streams and upon > deallocation it closes the stream, removes it from the runloop and releases > it (if arc is not enabled). This also removes a bug in non-arc environment > that where the streams have a retaincount of +1 after deallocation such that > the bug described here won't occur and the streams leak memory -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira