我正在使用 Objective-C分布式对象,并且在理解内存管理在系统下的工作方式时遇到了一些问题。下面给出的示例说明了我的问题:
协议.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;
}
客户端.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 的正确行为吗?所有临时对象都应该与创建它们的连接一样长吗?因此,连接是否应被视为临时对象,应在针对服务器的每一系列请求中打开和关闭?
任何见解将不胜感激。