1

我在我的应用程序中使用分布式对象来提供小型身份验证代理程序和主应用程序之间的通信。主应用程序产生 NSTask,它反过来会调用身份验证程序,而身份验证程序又会回调主程序以获取一些用户凭据。我知道这听起来很复杂,但它必须以这种方式工作,因为 ssh 从 SSH_ASKPATH 中的程序获取密码的方式。

在我的主应用程序中,我有一个名为 PasswordDialog 的对象的单个实例,我将其出售如下;

PasswordDialog *vendedPasswordDialog=[[PasswordDialog alloc] init];  
[[NSConnection defaultConnection] setRootObject:vendedPasswordDialog];
[[NSConnection defaultConnection] registerName:@"MyConnectionName"]

这在应用程序启动时发生一次。

在身份验证代理中,我回调这个对象如下;

NSConnection *passwordDialogConnection = [NSConnection connectionWithRegisteredName:@"MyConnectionName" host:nil];

PasswordDialog *pdProxy = (PasswordDialog*)[passwordDialogConnection rootProxy];

NSString *responseStr = [pdProxy responseForPID:pidString host:hostnameString user:usernameString processInfo:[NSProcessInfo processInfo]];

问题是这不像我想要的那样工作。如果有多个身份验证代理同时执行,我发现它们都可以访问同一个对象并同时调用同一个方法。例如,如果我在“responseForPID”的开头放置一个日志语句,最后我得到这样的输出;

beginMethod PID 3618848 on thread <NSThread: 0x30b050>{name = (null), num = 1} for object <PasswordDialog: 0x485460>
beginMethod PID 4882384 on thread <NSThread: 0x30b050>{name = (null), num = 1} for object <PasswordDialog: 0x485460>
beginMethod PID 4872848 on thread <NSThread: 0x30b050>{name = (null), num = 1} for object <PasswordDialog: 0x485460>

PID endMethod 4872848
PID endMethod 4882384
PID endMethod 3618848

似乎有三个不同的进程在具有相同地址的对象的同一线程上输入我的方法。显然我在这里缺少对分布式对象和线程的一些基本理解,但这似乎很神奇?

所以最终我得到了我的问题

(a)有人可以解释这里发生了什么(即我如何获得上面的日志语句)

(b) 显然,出于我的目的,我错误地使用了分布式对象。谁能建议我如何正确地做到这一点。

感谢并感谢您阅读到这个问题的结尾!


编辑:只是为了澄清。我的“responseForPID”方法看起来像这样;

- (NSString*) responseForPID:(NSString*) pid host:(NSString*)hostname user:(NSString*) username processInfo:(NSProcessInfo*) info {

NSLog(@"beginMethod PID %@ on thread %@ for object %@",pid,[NSThread currentThread],self);

.... code to get the password 

NSLog(@"PID endMethod %@",pid);
return passwordString;

}
4

1 回答 1

1
beginMethod PID 3618848 on thread <NSThread: 0x30b050>{name = (null), num = 1} for object <PasswordDialog: 0x485460>
beginMethod PID 4882384 on thread <NSThread: 0x30b050>{name = (null), num = 1} for object <PasswordDialog: 0x485460>
beginMethod PID 4872848 on thread <NSThread: 0x30b050>{name = (null), num = 1} for object <PasswordDialog: 0x485460>

PID 都不同,表示线程在不同的进程中执行。

所以,不,在单个线程上不能同时访问该方法。线程 ID 相同可能是巧合;由于这三个进程相对简单并且以相同的方式启动,因此线程碰巧分配在每个进程中的相同地址(或者,更可能的是,由于应用程序初始化的性质,主线程始终位于同一地址)。

当您喷出这些日志行时尝试打印[NSThread currentThread],而不仅仅是来自远程进程的字符串。

于 2009-09-27T00:27:00.620 回答