我正在尝试从Cocoa应用程序运行Python脚本.它在主线程上运行得很好,但是我希望它在后台运行,并发GCD队列.
我正在使用以下方法来设置运行Python脚本的管理器类:
- (BOOL)setupPythonEnvironment {
if (Py_IsInitialized()) return YES;
Py_SetProgramName("/usr/bin/python");
Py_Initialize();
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"MyScript" ofType:@"py"];
FILE *mainFile = fopen([scriptPath UTF8String], "r");
return (PyRun_SimpleFile(mainFile, (char *)[[scriptPath lastPathComponent] UTF8String]) == 0);
}
Run Code Online (Sandbox Code Playgroud)
之后,使用manager类的共享单例实例从以下实例方法(重复)调用脚本:
- (id)runScriptWithArguments:(NSArray *)arguments {
return [NSClassFromString(@"MyScriptExecutor") runWithArguments:arguments];
}
Run Code Online (Sandbox Code Playgroud)
上面的Objective-C代码挂钩到以下Python代码:
from Foundation import *
def run_with_arguments(arguments):
# ...a long-running script
class MyScriptExecutor(NSObject):
@classmethod
def runWithArguments_(self, arguments):
return run_with_arguments(arguments)
Run Code Online (Sandbox Code Playgroud)
当我总是从主队列运行上述Objective-C方法时,这可以工作,但是当从任何其他队列运行时,脚本返回null.有人可以解释一下,如果我想要做的事情不被支持,是否有一个好的方法呢?
经常调用Python脚本并运行很长时间,因此在主线程上执行此操作会太慢,而是从串行队列中运行它.另外,我想尽可能地在Objective-C中包含并发代码.
谢谢,
我正在尝试在iOS5中同步以下代码:
这是(简化)代码:
- (void)insideSomeMethod
{
[SomeHTTPRequest withCompletionHandler:
^(id retrievedData)
{
if(!retrievedData)
{
handler(nil);
}
// Populate CoreData model with retrieved Data...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]];
aCoreDataNSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL];
});
handler(aCoreDataNSManagedObject);
[self shouldCommitChangesToModel];
}];
}
- (void)shouldCommitChangesToModel
{
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSError *error = nil;
if(![managedObjectContext save:&error])
{
// Handle error
}
});
}
Run Code Online (Sandbox Code Playgroud)
但是,正在发生的是基于屏障的保存块总是在图像加载块之前执行.那是,
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSError *error = nil;
if(![managedObjectContext save:&error])
{
// Handle error
} …Run Code Online (Sandbox Code Playgroud) concurrency cocoa-touch grand-central-dispatch ios objective-c-blocks
我目前正在尝试加载Flickr Photo的UITableView列表(cs193p iOS Stanford,作业5).为了避免UI阻塞事件,我将每个单元的缩略图下载推迟到不同的队列(但是在主队列中更新UI).此代码不会异步加载图像,但是一旦我单击UITableViewCell行,就会添加缩略图.(见下面的截图).知道我做错了什么吗?
PS:我已经看过其他一些stackoverflow问题和Apple的LazyTableImages示例,但我仍然相信这是达到预期结果的最简洁方法.
谢谢!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Photo List Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell
NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];
if (photo != nil) {
if ([[photo objectForKey:@"title"] length] > 0) {
cell.textLabel.text = [photo objectForKey:@"title"];
} else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
} else {
cell.textLabel.text = @"Unknown";
}
}
cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];
// Fetch …Run Code Online (Sandbox Code Playgroud) 我正在显示一些文本和图像UITableView.首先下载图像.从图像下载之前,我不知道图像的大小,所以我最初放了UIImageView一些固定的大小.当下载图像时,我调整了大小UIImageView.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Download image
dispatch_async(dispatch_get_main_queue(), ^{
// UIImageView resizing
});
});
Run Code Online (Sandbox Code Playgroud)
所有这些都发生在cellForRowAtIndexPath.
我在这里
遇到的问题是:1.如何更新细胞的高度?考虑到单个单元格中可能存在许多图像.所以我需要在下载时更改底部图像的位置.
2.我尝试使用UITableView beginUpdates和endUpdates,但滚动到单元格的顶部,给用户带来糟糕的体验.
这就是uload在reloadData上的样子.有5个图像需要下载:UITableView reloadData之后的UI体验
在GCD上阅读Swift 3 evolution之后,我正在尝试创建调度组.问题是group.notify(queue:当我DispatchQueue.main作为队列传递时不通知,尽管它确实适用于后台队列.
此外,我不确定我的语法是否正确,因为我试图将代码从Swift 2转换为Swift 3.
typealias CallBack = (result: Bool) -> Void
func longCalculations (completion: CallBack) {
let backgroundQ = DispatchQueue.global(attributes: .qosBackground)
let group = DispatchGroup()
var fill:[Int] = []
for item in 0...200 {
group.enter()
if item > 50 {
fill.append(item)
}
group.leave()
}
//Below in the notify argument If I pass `backgroundQ`, it seems to work correctly but not when DispatchQueue.main is passed.
Run Code Online (Sandbox Code Playgroud)
此代码不起作用
group.notify(queue: DispatchQueue.main, execute: {
completion(result: true)
})
}
Run Code Online (Sandbox Code Playgroud)
这工作正常 …
我对GCD如何工作有一个很好的想法,但我想更多地了解被吹捧的"操作系统管理"内部.几乎所有关于Grand Central Dispatch如何与"操作系统"协同工作的技术解释都完全不同.我会解释一些我的发现.
"它是一个守护程序,它是操作系统的全局,可以在许多核心上分配任务."
我并不傻到相信这一点.
"内核中内置了支持以了解所有GCD应用程序.GCD应用程序与内核协同工作,就如何管理应用程序中的线程做出逻辑决策."
听起来这种同步方案比仅仅管理应用程序中的逻辑要慢得多.
"GCD仅存在于应用程序中,并使用当前系统负载作为其行为的度量标准."
这对我来说听起来更真实,但我只在一个地方看到了这样的陈述.
这里到底发生了什么?它只是一个图书馆,还是整个"系统"?
我有自己的方法,以块作为参数.我想跟踪NSDictionary中的那个块.将块添加到字典的最佳方法是什么?
我尝试了这段代码但是在执行下面的行(setObject ...)后,字典仍然是空的.我认为这是因为该块不是NSObject类型.但是这样做的正确方法是什么?
- (void)startSomething:(NSURLRequest*)request block:(void (^)(NSURLResponse*, NSData*, NSError*))handler {
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[pendingRequests setObject:handler forKey:connection];
}
Run Code Online (Sandbox Code Playgroud)
编辑:
没关系.我不知道我在想什么.3分:
无论如何我现在解决了我的问题:
- (void)startSomething:(NSURLRequest*)request block:(void (^)(NSURLResponse*, NSData*, NSError*))handler {
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[pendingRequests setValue:handler forKey:[connection description]];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
void (^handler)(NSURLResponse*, NSData*, NSError*);
handler = [pendingRequests valueForKey:[connection description]];
handler(nil, nil, nil);
});
}
Run Code Online (Sandbox Code Playgroud) 我正在使用parse.com API开发一个应用程序(托管后端提供API以在其服务器上保存数据).我希望能够在线和离线无缝使用该应用程序.为此,我需要使用一个队列,我可以放置需要网络访问的块.当网络确实可用时,应该串行执行这些块,当网络脱机时,应该暂停队列处理.
当网络变得可用/不可用时,我正在考虑将GCD用于暂停/恢复.我想知道是否有更好的选择?如果将应用程序放在后台,这会有效吗?这里的一个例子是,当网络不可用(排队等待)然后将应用程序置于后台时,用户会保存一些数据.现在,当网络可用时,是否可以自动在后台进行保存?
queue grand-central-dispatch reachability ios parse-platform
要在主线程上执行"stuff",我应该使用dispatch_async还是performSelectorOnMainThread?是否有首选方式,正确/错误和/或最佳做法?
示例:我在NSURLConnection sendAsynchronousRequest:urlRequest方法块中执行某些逻辑.因为我正在做主要视图的东西,比如呈现UIAlertView我需要UIAlertView在主线程上显示.为此,我使用以下代码.
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped out to keep this question short
if(![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
});
}
}];
Run Code Online (Sandbox Code Playgroud)
在同一个if(![NSThread isMainThread])声明中,我也称之为一些自定义方法.问题是,我应该dispatch_async使用上面使用的方法还是更好地使用performSelectorOnMainThread?例如,下面的完整代码:
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped …Run Code Online (Sandbox Code Playgroud) asynchronous objective-c nsthread grand-central-dispatch ios
我想在我的应用程序中显示一个ActivityIndicatorView,但是当我sync从主线程调用该方法时,应用程序崩溃并出现错误:exc_bad_instruction (code=exc_i386_invop subcode=0x0)
我正在使用xcode 8.0和swift 3
有人可以帮帮我吗?
func POST(endpoint:NSString!,body:NSString!,vc:UIViewController? = nil)->NetworkResult{
let result = NetworkResult()
DispatchQueue.main.sync {
self.displayActivityIndicator(viewController: vc)
}
let urlStr = self.url.appending(endpoint as String).appending(self.getHashAutenticacao() as String)
print(urlStr)
let request = NSMutableURLRequest(url: URL(string: urlStr)!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20)
print(request.debugDescription)
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = body.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: true)
// send the request
var data: NSData!
do {
data = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning: &self.response) as NSData!
} catch let …Run Code Online (Sandbox Code Playgroud) ios ×8
objective-c ×3
swift ×2
swift3 ×2
uitableview ×2
asynchronous ×1
cocoa-touch ×1
concurrency ×1
nsdictionary ×1
nsthread ×1
python ×1
queue ×1
reachability ×1
uiimageview ×1