我正在尝试在后台线程中运行NSTask并在NSTextview中显示其输出,该NSTextview使用readInBackgroundAndNotify附加到我的窗口(Preference Pane)上的NSPanel我似乎不接收通知作为应该调用的方法不是.
我有控制器类(PreferencePane.m)初始化负责运行NSTask的类(Inventory.m)
- (IBAction)updateInventoryButtonPressed:(id)sender
{
inventory = [[Inventory alloc] init];
....
Run Code Online (Sandbox Code Playgroud)
然后我发送一个NSNotification来启动后台(来自PreferencePane.m):
....
[[NSNotificationCenter defaultCenter]
postNotificationName:NotificationInventoryRequested
object:self];
}
Run Code Online (Sandbox Code Playgroud)
此类(Inventory.m)是其init重写中此常量(NotificationInventoryRequested)的观察者
- (id)init
{
[super init];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(inventoryRequested:)
name:NotificationInventoryRequested
object:nil];
return self;
}
Run Code Online (Sandbox Code Playgroud)
这将运行inventoryRequested方法(Inventory.m)
-(void)inventoryRequested:(NSNotification*)aNotification
{
if (inventoryIsRunning) {
NSLog(@"Inventory is already running, ignoring request");
}
else {
NSLog(@"Starting Inventory in background...");
[NSThread detachNewThreadSelector:@selector(runInventoryTask)
toTarget:self
withObject:nil];
}
}
Run Code Online (Sandbox Code Playgroud)
这运行我的NSTask方法,我已经从示例中重构了几次
设置BOOL以帮助重复运行完整性由inventoryRequested使用ivar inventoryIsRunning处理
-(void)runInventoryTask
{
inventoryIsRunning = YES;
....
Run Code Online (Sandbox Code Playgroud)
我仔细检查我的任务并设置readInBackgroundAndNotify将我自己添加为观察者.
....
if (task) {
NSLog(@"Found existing task...releasing");
[task release];
}
task …Run Code Online (Sandbox Code Playgroud) cocoa objective-c nstask nsnotifications nsnotificationcenter
try:
for key in copy['KnownNetworks'].keys():
if copy['KnownNetworks'][key]['SSID_STR'] == networkDict['name']:
networkDict['uuid'] = copy['KnownNetworks'][key]['Unique Password ID']
print 'Found existing reference to wireless password uuid: %s' % networkDict['uuid']
found = True
except:
print 'Key KnownNetworks not found'
# Clean up top level key
keychain = '/Library/Keychains/System.keychain'
arguments = [security,"add-generic-password",'-a',networkDict['name'],'-l',networkDict['name'],'-D','Airport network password','-s',networkDict['uuid'],'-w',networkDict['pass'],'-T','group://Aiport','-T','/System/Library/CoreServices/SystemUIServer.app','-T','/Applications/System Preferences.app','-T','/usr/libexec/airportd',keychain]
addKeychainPassword(arguments)
users = '/var/db/dslocal/nodes/Default/users'
listing = os.listdir(users)
for plist in listing:
Run Code Online (Sandbox Code Playgroud)
我有一个格式化问题,就是上面的例子,是否有更好的方法来格式化参数列表声明?它是一个子进程调用,所以我需要它作为一个列表,但我想我可以将它转换为字典然后返回列表.我的主要目标是,我希望它适合大多数unix脚本的80 col标准.您想要在清洁代码方面分享哪些技术?
我正在使用IOKit并拥有以下代码,一般的想法是将platformExpert密钥传递给这个小的核心基础命令行应用程序并让它打印解码后的字符串.测试用例是"序列号".运行时的代码如下:
./编译的序列号
几乎可以工作,但在字符串的开头返回序列号的最后4个字符,即对于C12D2JMPDDQX等示例序列,它将返回
DDQXC12D2JMPDDQX
有任何想法吗?
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
int main (int argc, const char * argv[]) {
CFStringRef parameter = CFSTR("serial-number");
if (argv[1]) {
parameter = CFStringCreateWithCString(
NULL,
argv[1],
kCFStringEncodingUTF8);
}
CFDataRef data;
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpert)
{
data = IORegistryEntryCreateCFProperty(platformExpert,
parameter,
kCFAllocatorDefault, 0);
}
IOObjectRelease(platformExpert);
CFIndex bufferLength = CFDataGetLength(data);
UInt8 *buffer = malloc(bufferLength);
CFDataGetBytes(data, CFRangeMake(0,bufferLength), (UInt8*) buffer);
CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault,
buffer,
bufferLength,
kCFStringEncodingUTF8,
TRUE);
CFShow(string);
return 0;
}
Run Code Online (Sandbox Code Playgroud)