小编And*_*rea的帖子

从 NSOperationQueue 取消 NSOperation 导致崩溃


我正在尝试构建一个下载管理器类,它将所有异步下载(每个操作都有自己的线程)操作打包到 NSOperation 子类中,以便稍后将它们添加到 NSOperationQueue 中。下载管理器类(单例)还公开了一些方法来处理队列并取消符合某些要求的操作。
这些是开始创建类集群(抽象工厂)的步骤,该类集群为不同类型的常见操作(上传、下载、解析等)返回不同类型的 NSOperation。
该类似乎可以很好地处理下载操作,但如果在这些操作中间我调用取消操作的方法,则该操作会成功取消,但应用程序会在稍后的几个操作中崩溃。如果我不取消任何操作,一切都会正常。所有操作均使用 KVO 进行观察。删除操作的方法如下所示:

- (void) cancelDownloadOperationWithID:(NSString *)aUUID{
@synchronized(self){
    [self.dowloadQueue setSuspended:YES]; //downloadQueue is an NSOperationQueue
    NSArray * downloadOperations = [self.dowloadQueue operations];
    NSPredicate * aPredicate = [NSPredicate predicateWithFormat:@"SELF.connectionID == %@",aUUID]; //SELF is the signleton instance of the download manager
    NSArray * filteredArray = [downloadOperations filteredArrayUsingPredicate:aPredicate];
    if ([filteredArray count]==0) {
        [self.dowloadQueue setSuspended:NO];
        return;
    } 
    [filteredArray makeObjectsPerformSelector:@selector(cancel)];
    NSLog(@"Cancelled %d operations",[filteredArray count]);
    [self.dowloadQueue setSuspended:NO];
   }
}
Run Code Online (Sandbox Code Playgroud)

崩溃日志非常难以理解,但是是一个 BAD_EXC_ACCESS (可能是僵尸),请注意我处于 ARC 下。

0x00a90ea8  <+0393>  jle    0xa90d9f <____NSOQSchedule_block_invoke_0+128>
0x00a90eae  <+0399> …
Run Code Online (Sandbox Code Playgroud)

iphone download nsoperation nsoperationqueue ios

3
推荐指数
1
解决办法
4715
查看次数

在守卫声明中迅速使用休息

我试图break在一个guard声明中使用,但编译器告诉我

'break'只允许在循环内,if,do或switch

是否有可能写出这个片段(这只是一个MCV)?

   func test(string: String?, x: Int) {
        print("Function Scope BEGIN")
        if x > 4 {
            guard let pr = string else { break }
            print(pr)
        }
        else {
            print("Not")
        }
        print("Function Scope END")
    }
Run Code Online (Sandbox Code Playgroud)

if-statement guard optional swift

3
推荐指数
1
解决办法
3213
查看次数

使用VM跟踪器进行iOS分析.脏和常驻内存导致内存警告,我该怎么办?


你好社区,我正在尝试调试我没做的.这个应用程序在线工作并缓存文件系统上的所有内容,保存内存上的所有路径(很多路径)(我看到错误的方法,但我必须努力).这个应用程序有一个选项,可以下载所有内容并用相对路径填充内存.
问题是,当我检查此选项时,应用程序开始下载和缓存,但在它完成之前崩溃.在模拟器上一切正常.
崩溃报告日志讨论了由jetsam杀死的内存警告和应用程序.通过仪器上的分配来跟踪应用程序我发现实时字节"仅仅"大约7Mb,使用在下载期间添加的刷新机制也有帮助,在下载完成后释放旧路径.
根本没有明显的泄漏.
我开始使用VMTracker,我已经看到驻留和脏内存非常高,峰值在61Mb和21Mb左右.有一些我没有得到的东西.
我已经阅读了很多关于它的问题
"虚拟"和"居民"与虚拟记忆有什么关系?
如何摆脱Objective-C中的常驻脏内存?
但是,因为我发布了其他脏内存来自的大多数路径?我该如何清洁它?
谢谢,
安德烈

memory iphone memory-management ios memory-warning

2
推荐指数
1
解决办法
4487
查看次数

NSOperationQueue,并发操作和线程

我正在开发一种快速图像扫描应用程序.
-captureOutput:didOutputSampleBuffer:fromConnection:方法中,我拿起CVPixelBuffer并将它们添加到NSOperation子类中.该NSOperation取缓冲,并将其转化为保存在文件系统中的图像.返回
-isConcurrent方法是NSOperationYES.创建操作后,添加到NSOperationQueue.
除了影响扫描帧速率的一个问题外,一切运行正常.
使用时间分析器我发现一些NSOperation运行在我创建的AVCaputureVideoOutput委托的同一个线程上:

dispatch_queue_t queue = dispatch_queue_create("it.CloudInTouchLabs.avsession", DISPATCH_QUEUE_SERIAL);
[dataOutput setSampleBufferDelegate:(id)self queue:queue];
Run Code Online (Sandbox Code Playgroud)

当一个操作在AV会话队列的同一个线程上运行时,它会影响帧速率,它只发生在它们中的一些,可能GCD正在决定在活动线程上调度.
我发现解决该问题的唯一方法是创建一个单独的线程并将其传递给单个操作,强制它们在其上运行.
还有另一种方法,强制在不同的线程上运行操作吗?

[编辑]
按照@impcc的建议我做了一些测试.
即使有些不一致,结果也很有趣.
测试平台是一个通过MBP与调试模式连接的iPhone 5,具有16GB的RAM四核i7.会话使用RosyWriter apple示例代码中的算法测试了60fps的输出.
AVSession队列同步针对高优先级队列

  • 26 fps,有时队列的线程与其中一个操作共享.委托方法内部的时间平均为0.02秒

  • 14 fps,只为操作创建一个线程,如果在该线程上没有调用main方法,则将强制启动该特定线程.这个线程创建一次并使用虚拟端口保持活动状态..代理内部的时间为0.008.

AVSession队列并发目标为高优先级队列

  • 13.5 fps,有时队列的线程与其中一个操作共享.委托方法内部所花费的时间平均为0.02秒,与具有同步队列的对应物相等.

  • 14 fps,只为操作创建一个线程,如果在该线程上没有调用main方法,则将强制启动该特定线程.这个线程创建一次并使用虚拟端口保持活动状态.代表内部的时间是0.008.

结论
并发或串行队列似乎没有太大的区别,但是对我而言并发是不正确的,因为我需要采取时间戳来保留单个图片的序列.让我感到惊讶的事实是使用ad-hoc线程的帧丢弃,即使委托方法内部所花费的时间相当少,帧速率也会下降大约10fps.只是信任GCD,帧速率更好,但委托方法需要2次以上才能完成,这可能是因为有时AV队列也被nsoperations使用.
我无法理解为什么委托内部的时间似乎与fps无关.不应该越快越好?
通过进一步的研究,似乎在添加并可能在队列中执行操作的过程中窃取时间si.

multithreading nsoperation nsoperationqueue grand-central-dispatch ios

2
推荐指数
1
解决办法
1246
查看次数

一个iOS应用程序是否支持多个推送通知注册?


这是我第一次接近推送通知服务,我有点困惑.我想提供一些概念上的帮助,而不是代码.
我需要构建一个应该接收和注册不同类型通知的应用程序.例如,在我的应用程序中,我希望用户可以注册PROMO通知类别和NEWS通知类别,我希望他们可以选择他们想要通知哪一个.
阅读Apple文档,这对我来说并不是那么清楚,似乎一旦app设备被注册,我只收到一个令牌,似乎无法接收更多令牌用于不同类型的注册(例如NEWS和PROMO),因为令牌与应用程序和设备有关.那是对的吗?
对我来说另一件不太清楚的事情是,如果设备注册了特定通知,是否可以仅将通知发送给设备?

如果Apple推送服务没有提供任何内容,您认为可以管理这样的一切: - 如果选择了(PROMO || NEWS),我会注册应用设备以获取通知 - 我获取令牌 - 我将令牌发送到我的服务器还提供了有关用户想要订阅的服务的附加信息 - 服务器(提供商)注册令牌和订阅类型(PROMO || NEWS) - 当我有通知推送时我要求服务器全部为该特定类别注册的令牌,然后我仅将通知发送给为该类别注册的设备.


谢谢你帮助我,我真的很困惑.

iphone notifications push-notification apple-push-notifications ios

1
推荐指数
1
解决办法
3531
查看次数

NSFetchRequest也提取我的实体类型的子类

我在表视图中使用了一个获取的结果控制器,一切正常,除了请求还获取我的实体类型的子类这一事实,我不会.有没有办法做到这一点?控制器以通常的方式实例化.

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for …
Run Code Online (Sandbox Code Playgroud)

iphone core-data nsfetchrequest ios

0
推荐指数
1
解决办法
410
查看次数