ios - 写入流 iOS 时的自旋锁(仅在模拟器上)

标签 ios objective-c cocoa-touch

每当我将应用程序发送到后台时,我都会收到旋转锁定错误。这是最小化应用程序时的代码:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    if (savedResults || savedSchedule || watchingClasses || professors) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *docDir = [paths objectAtIndex:0];
        NSString *fullPath = [docDir stringByAppendingFormat:@"/%@", kFileName];
        NSMutableArray *array = [NSMutableArray arrayWithCapacity:4];
        if (!savedResults)  {
            [array addObject:[NSNull null]];
        }else {
            [array addObject:savedResults];
        }
        if (!savedSchedule) {
            [array addObject:[NSNull null]];
        }else {
            [array addObject:savedSchedule];
        }
        if (!watchingClasses) {
            [array addObject:[NSNull null]];
        }else {
            [array addObject:watchingClasses];
        }
        if (!serverAnnouncements) {
            [array addObject:[NSNull null]];
        }else {
            [array addObject:serverAnnouncements];

        }if (!professors) {
            [array addObject:[NSNull null]];
        }else {
            [array addObject:professors];
        }
        [NSKeyedArchiver archiveRootObject:[array copy] toFile:fullPath];
    }
        //close connection
    if (outputStream) {
        if ([outputStream hasSpaceAvailable]) {
            dispatch_queue_t task = dispatch_queue_create("Close Connection", nil);
            NSString *str = @"_CLOSE_CONNECTION*\n";
            NSData *dataToSend = [[NSData alloc] initWithData:[str dataUsingEncoding:NSUTF8StringEncoding]];
            dispatch_async(task, ^{
                [outputStream write:[dataToSend bytes] maxLength:[dataToSend length]];
            });
        }
    }
    [inputStream close];
    [outputStream close];
    inputStream = nil;
    outputStream = nil;
    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    initializedSocket = NO;

    [FlurryAds setAdDelegate:nil];
}

我在 ouputStream 写入方法上收到 EXC_BAD_ACCESS。我还附上了屏幕截图。 Image

最佳答案

看起来像一个悬空指针。

该流在 ivar 中被引用,因此您的分派(dispatch) block 仅保留 self,而不是 self->outputStream。当您在分派(dispatch) block 后立即清除 ivar 时,对它的唯一强引用就会消失,并且流在仍在使用时会被释放,从而导致崩溃。

为了避免这个问题,请确保您的 block 通过使用本地范围的变量而不是 ivar 来维护对流的强引用:

NSOutputStream *os = self->outputStream;
dispatch_async
(
    ...,
    ^ {
        [os write:...];
    }
);

注意,在这里为这一个 block 创建调度队列是没有意义的;你应该只使用全局队列。

关于ios - 写入流 iOS 时的自旋锁(仅在模拟器上),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14404935/

相关文章:

objective-c - NSMutableArray : replaceObjectAtIndex vs assignment

ios - 扑克手排名循环组合

objective-c - iOS 超时功能无法正常工作

iphone - 选择另一个日历时 EKEvent 标识符发生变化

javascript - UIWebView 使用 elementFromPoint() 获取图片 url

ios - 从多个 View Controller 接收委托(delegate)方法调用

ios - TableView 以编程方式滚动到顶部后,UIRefreshControl 不会消失

ios - 归档 IOS 应用程序时无法导入桥接头

c# - 创建一个使用 CAGradientLayer 作为其层的 UIView 子类

objective-c - 带有用于 Objective-C 的 ClientLogin 接口(interface)的 Google App Engine