写入流iOS时旋转锁定(仅在模拟器上)

时间:2013-01-18 18:06:50

标签: 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

1 个答案:

答案 0 :(得分:1)

看起来像一个悬垂的指针。

该流在ivar中被引用,因此您的已分派数据块仅保留self,而不是self->outputStream。当您在调度块之后清除ivar时,对它的唯一强引用就会消失,并且在仍在使用时会释放该流,从而导致崩溃。

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

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

请注意,为此一个块创建一个调度队列没有意义;你应该只使用全局队列。