我在GitHub上创建了一个项目,这样我就可以学习如何为我的iOS应用程序优化网络.我已经大量使用了块和GCD,在观看过去几年的WWDC 2012视频和视频后,我了解到我可以用NSOperationQueue做更多的事情.具体来说,我可以控制并发操作(网络连接)的数量以及提供操作的取消.我正在尝试允许1,2,4,8和16个并发操作,我看到有趣的结果,我并不完全期望.我正在测量结果,但我想知道是否还有更多我应该测量的.
你可以在这里找到示例项目:
https://github.com/brennanMKE/OptimizedNetworking
由于我使用NSURLConnection的异步API,因此许多并发连接有很多好处,因为API花费了大量时间等待HTTP数据包.以前我的代码将从一个要下载的项目数组开始,并按顺序请求它们,这会阻止并发的好处.我也一直在使用通知来取消网络连接.现在我可以通过操作来完成这个项目,我已经将它们设置为使用优先级值和类别,以便我可以对下载进行优先级排序和排序,并取消一类操作.我可以选择为每个视图使用一个类别,当用户离开视图时,将使用该类别取消该视图的所有操作.这将释放活动视图的资源.
使用更多并发操作的一个问题是CPU使用率和I/O,但我不知道使用iOS测量这些值的方法.相当于iOS中的"w"命令以显示CPU使用率可能很有用.我不太关心I/O,但测量它会更全面.
我在网络方面的主要问题是响应式用户界面.我发现我一直在做的事情让UI变得迟钝.这种新方法可能有很大帮助,但前提是我保持并发操作的数量.最佳操作数可能因连接类型(3G,WiFi等)而异,因此检查连接类型可能会导致一些优化.
如果您对加速应用程序中网络通信的更好方法感兴趣,请尝试此示例项目,并提出其他方法来衡量性能并提供进一步优化通信的方法.(另请注意,我正在引用Apple示例项目MVCNetworking以及ASIHTTPRequest项目.
接下来我要做的是总计下载的数据量并保留该数量的日志以及完成下载的总时间.
README文件应该有助于解释项目及其工作原理.
xCode 4.4.1 OSX 10.8.2,看起来像[operation cancelAllOperations]; 不工作
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSOperationQueue *operation = [[NSOperationQueue alloc] init];
[operation setMaxConcurrentOperationCount: 1];
[operation addOperationWithBlock: ^{
for (unsigned i=0; i < 10000000; i++) {
printf("%i\n",i);
}
}];
sleep(1);
if ([operation operationCount] > 0) {
[operation cancelAllOperations];
}
}
Run Code Online (Sandbox Code Playgroud)
结果9999999
Apple文档说,如果将NSOperationQueue的maxConcurrentOperationCount属性设置为NSOperationQueueDefaultMaxConcurrentOperationCount(默认值),则它将根据"系统条件"在运行时调整该值.
如果指定值NSOperationQueueDefaultMaxConcurrentOperationCount(建议使用),则最大操作数可以根据系统条件动态更改.
任何人都可以报告他们在不同设备上看到的那些价值在野外被设置的东西吗?对于旧手机,我们是说1或2,对于新型号,我们是3-4,或者10或?? 它没有给出可能性设置或最常见结果的任何见解.我认为开发人员知道在生产中会发生什么会有所帮助,而不仅仅是我们会在不解释他们优化的内容(UI响应,操作执行速度等)的情况下处理它.
我正在开发一个创建内容并将其发送到现有后端的应用程序.内容是标题,图片和位置.没有什么花哨.
后端有点复杂,所以这就是我要做的事情:
我已经使用了几个NSOperation子类来完成这项工作,但我并不为我的代码感到自豪,这里有一个示例.
NSOperation *process = [NSBlockOperation blockOperationWithBlock:^{
// Process image before upload
}];
NSOperation *filename = [[NSInvocationOperation alloc] initWithTarget: self selector: @selector(generateFilename) object: nil];
NSOperation *generateEntry = [[NSInvocationOperation alloc] initWithTarget: self selector: @selector(createEntry) object: nil];
NSOperation *uploadImage = [[NSInvocationOperation alloc] initWithTarget: self selector: @selector(uploadImageToCreatedEntry) object: nil];
NSOperation *refresh = [NSBlockOperation blockOperationWithBlock:^{
// Update UI
[SVProgressHUD showSuccessWithStatus: NSLocalizedString(@"Success!", @"Success HUD message")];
}];
[refresh addDependency: uploadImage];
[uploadImage addDependency: generateEntry];
[generateEntry addDependency: filename];
[generateEntry addDependency: process];
[[NSOperationQueue …
Run Code Online (Sandbox Code Playgroud) 我第一次使用Objective-C块和操作队列.我正在加载一些远程数据,而主UI显示一个微调器.我正在使用完成块告诉表重新加载其数据.正如文档中提到的那样,完成块不会在主线程上运行,因此表会重新加载数据,但在主线程上执行某些操作(例如拖动表)之前不会重新绘制视图.
我现在使用的解决方案是一个调度队列,这是从完成块刷新UI的"最佳"方法吗?
// define our block that will execute when the task is finished
void (^jobFinished)(void) = ^{
// We need the view to be reloaded by the main thread
dispatch_async(dispatch_get_main_queue(),^{
[self.tableView reloadData];
});
};
// create the async job
NSBlockOperation *job = [NSBlockOperation blockOperationWithBlock:getTasks];
[job setCompletionBlock:jobFinished];
// put it in the queue for execution
[_jobQueue addOperation:job];
Run Code Online (Sandbox Code Playgroud)
更新 Per @ gcamp的建议,完成块现在使用主操作队列而不是GCD:
// define our block that will execute when the task is finished
void (^jobFinished)(void) = ^{
// …
Run Code Online (Sandbox Code Playgroud) 我是GCD和线程的新手.我已经完成了教程并且非常困惑.有人可以用简单的话来解释.请不要建议苹果开发者链接..
提前致谢 !
iphone multithreading nsoperationqueue grand-central-dispatch nsinvocation
我有这些方法从互联网上检索一些对象信息:
- (void)downloadAppInfo:(void(^)())success
failure:(void(^)(NSError *error))failure;
- (void)getAvailableHosts:(void(^)())success
failure:(void(^)(NSError *error))failure;
- (void)getAvailableServices:(void(^)())success
failure:(void(^)(NSError *error))failure;
- (void)getAvailableActions:(void(^)())success
failure:(void(^)(NSError *error))failure;
Run Code Online (Sandbox Code Playgroud)
下载的东西存储在对象属性中,这就是成功函数不返回任何内容的原因.
现在,我想要一个像这样的方法:
- (void)syncEverything:(void(^)())success
failure:(void(^)(NSError *error))failure;
Run Code Online (Sandbox Code Playgroud)
除了调用上面的所有方法之外,它只会在每个方法执行其成功或失败块之后返回.
我怎样才能做到这一点?
提示:我知道级联方法调用彼此成功块会起作用.但是,当后来的实现包括更多方法时,这既不"干净"也不有用.
尝试:
我尝试在a中运行每个调用NSOperation
并将其添加NSOperations
到a NSOperationQueue
后跟"完成操作",这取决于前面的每个操作.
这不行.由于即使在各自的成功/失败块返回之前也认为操作已完成.
我也试过用dispatch_group
.但我不清楚我是以正确的方式做到这一点.不幸的是,它没有用.
nsoperation nsoperationqueue grand-central-dispatch ios objective-c-blocks
我对使用NSOperation
和绘图有一些建议:
我有一个主线程创建我的NSOperation
子类,然后将其添加到NSOperationQueue
.
我NSOperation
做了一些繁重的处理,它打算在main()方法中循环几分钟,不断处理一些工作,但是现在我只有一个while()循环,里面有一个sleep(1),设置为go大约只有5次(用于测试).
产生它的主(原始)线程NSOperation
负责绘制视图并更新UI.
我打算让NSOperation线程使用通知来告诉主线程它已经完成了一些处理,此时每次通过while()循环时都会发送一次这个通知(也就是说,每秒一次,因为它只是在做睡眠(1)).主线程(视图),注册接收这些通知.
通知立即进入主线程,看起来异步,看起来很好.似乎两个线程都按预期运行......即 - 同时运行.(我使用NSLog()来粗略检查每个线程何时发送和接收通知).
当视图收到通知并调用其处理程序方法时,我只是递增一个整数变量,并尝试将其绘制到视图中(当然是一个字符串).在测试中,drawRect中的代码:将此整数(作为字符串)绘制到屏幕上就好了.
但是:这是我的问题(抱歉这需要花一点时间才能到达):当主线程(视图)收到来自NSOperation的通知时,它会更新此测试整数并调用[self setNeedsDisplay].但是,在NSOperation完成之前,视图不会重绘!我期望NSOperation作为一个单独的线程,无法阻止主线程的事件循环,但看起来这就是正在发生的事情.当NSOperation完成并且其main()返回时,视图最终会立即重新绘制.
也许我没有NSOperation
正确使用.我在"非并发"模式下使用它,但尽管名称我的理解是这仍然产生一个新线程并允许异步处理.
任何帮助或建议非常感谢,如果您想看到一些代码,请告诉我.
我使用这种AFNetworking方法一次启动多个请求:
- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
completionBlock:(void (^)(NSArray *operations))completionBlock
Run Code Online (Sandbox Code Playgroud)
其中一个是AFJSONRequestOperation
.问题是此JSON操作的成功块是在批处理的完成块之后执行的.原因是:AFJSONRequestOperation
有一个用于JSON处理的内部调度队列.因此,在调用完成块时,JSON数据仍在处理中.
问题:如何在调用JSON操作的成功块之后在完成块中执行代码?
我试图在主队列上调度代码块,但这没有帮助.
我需要知道什么时候NSOperationQueue
从队列中删除一个操作?我有NSOperationQueue
哪个列表NSOperation
.从哪个位置NSOperationQueue
删除队列中的操作?
因为在NSOPerationqueue
完成所有操作后我需要通知.为此,我提到了 这个链接
nsoperationqueue ×10
ios ×8
nsoperation ×5
iphone ×3
cocoa-touch ×2
afnetworking ×1
cocoa ×1
networking ×1
nsinvocation ×1
objective-c ×1