Objective-C Distributed Objectsで遊んでいますが、システムでメモリ管理がどのように機能するかを理解するのに問題があります。以下の例は、私の問題を示しています。
プロトコル.h
#import <Foundation/Foundation.h>
@protocol DOServer
- (byref id)createTarget;
@end
サーバー.m
#import <Foundation/Foundation.h>
#import "Protocol.h"
@interface DOTarget : NSObject
@end
@interface DOServer : NSObject < DOServer >
@end
@implementation DOTarget
- (id)init
{
if ((self = [super init]))
{
NSLog(@"Target created");
}
return self;
}
- (void)dealloc
{
NSLog(@"Target destroyed");
[super dealloc];
}
@end
@implementation DOServer
- (byref id)createTarget
{
return [[[DOTarget alloc] init] autorelease];
}
@end
int main()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
DOServer *server = [[DOServer alloc] init];
NSConnection *connection = [[NSConnection new] autorelease];
[connection setRootObject:server];
if ([connection registerName:@"test-server"] == NO)
{
NSLog(@"Failed to vend server object");
}
else
{
while (YES)
{
NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
[[NSRunLoop currentRunLoop] runUntilDate:
[NSDate dateWithTimeIntervalSinceNow:0.1f]];
[innerPool drain];
}
}
[pool drain];
return 0;
}
Client.m
#import <Foundation/Foundation.h>
#import "Protocol.h"
int main()
{
unsigned i = 0;
for (; i < 3; i ++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id server = [NSConnection rootProxyForConnectionWithRegisteredName:@"test-server"
host:nil];
[server setProtocolForProxy:@protocol(DOServer)];
NSLog(@"Created target: %@", [server createTarget]);
[[NSRunLoop currentRunLoop] runUntilDate:
[NSDate dateWithTimeIntervalSinceNow:1.0]];
[pool drain];
}
return 0;
}
問題は、ルート プロキシによって作成されたリモート オブジェクトが、クライアント内の対応するプロキシがスコープ外になったときに解放されないことです。ドキュメントによると:
オブジェクトのリモート プロキシの割り当てが解除されると、受信者にメッセージが返され、ローカル オブジェクトが接続を介して共有されなくなったことを通知します。
したがってDOTarget
、接続のリモート側で保持されている他の参照がないため、それぞれが範囲外になると (ループのたびに)、リモートの相手が割り当て解除されると予想されます。
実際には、これは起こりません。一時オブジェクトは、クライアント アプリケーションが終了したとき、またはより正確には、接続が無効になったときにのみ解放されます。ループのたびに使用している NSConnection オブジェクトを明示的に無効にして新しいオブジェクトを作成することで、リモート側の一時オブジェクトの割り当てを強制的に解除できますが、どういうわけかこれは間違っているように感じます。
これは DO の正しい動作ですか? すべての一時オブジェクトは、それらを作成した接続が続く限り存続する必要がありますか? したがって、接続は、サーバーに対する一連のリクエストごとに開いたり閉じたりする必要がある一時オブジェクトとして扱われますか?
任意の洞察をいただければ幸いです。