简体   繁体   English

NSPOSIXErrorDomain代码= 12 3G网络中的“无法分配内存”

[英]NSPOSIXErrorDomain Code=12 “Cannot allocate memory” in 3G network

I'm trying to send a file on FTP server in my iPhone application. 我正在尝试在iPhone应用程序的FTP服务器上发送文件。 Everything seems to be okay in WiFi and GSM:EDGE network, but in 3G network an error appears (not always, but very often): WiFi和GSM:EDGE网络似乎一切正常,但是在3G网络中会出现错误(并非总是,但经常):

Error Domain=NSPOSIXErrorDomain Code=12 "The operation couldn't be completed. Cannot allocate memory" 错误域= NSPOSIXErrorDomain代码= 12“无法完成该操作。无法分配内存”

Below the code where the error appears: 出现错误的代码下面:

- (void)stream:(NSStream*)aStream handleEvent:(NSStreamEvent)eventCode {

    switch( eventCode ) {
        case NSStreamEventHasSpaceAvailable: {
            if( _readDataOffset == _readDataLimit ) {
                NSInteger readDataLen = [_readStream read:[_readData mutableBytes] maxLength:kReadDataLength];
                NSLog(@"readDataLen is %d",readDataLen);
                if( -1 == readDataLen ) {
                    _error = [[_readStream streamError] retain];
                    _keepRunning = NO;
                } else if( 0 == readDataLen ) {
                    _keepRunning = NO;
                } else {
                    _readDataOffset = 0;
                    _readDataLimit = readDataLen;
                }
            }

            if( _readDataOffset != _readDataLimit ) {
                NSOutputStream* writeStream = (NSOutputStream*)aStream;

                uint8_t *buffer = (void *)[_readData bytes];

          // vvvv and here  the value of writtenDataLen is often -1 (but only on 3G network)
                NSInteger writtenDataLen = [writeStream write:&buffer[_readDataOffset] maxLength:_readDataLimit - _readDataOffset]; 


                if( writtenDataLen > 0 ) {
                    _readDataOffset += writtenDataLen;
                    _writtenDataLen += writtenDataLen;
                    [self ftpPutDidWriteInternal];
                } else if( -1 == writtenDataLen ) {
                    _error = [[writeStream streamError] retain];
                    _keepRunning = NO;
                }
            }

        } break;
        case NSStreamEventErrorOccurred: {
            _error = [aStream.streamError retain];
            _keepRunning = NO;
        } break;
    }    
}

What can be important, the whole sending is done in separate thread which has it's own NSAutoreleasePool. 重要的是,整个发送是在具有自己的NSAutoreleasePool的单独线程中完成的。 Is there anyone who got the issue? 有谁遇到这个问题吗? Any suggestion? 有什么建议吗? I would be appreciate. 我将不胜感激。

UPDATE: I've just checked that popular iPhone application "FTP On The Go" has got the same (?) issue during sending a file in 3G network! 更新:我刚刚检查了流行的iPhone应用程序“ FTP On The Go”在3G网络中发送文件时是否遇到了相同(?)问题! There is no error handled, but the transfer stops. 没有错误处理,但传输停止。

UPDATE 2: I can't believe it, but it's true: SimpleFTPSample from Apple is also affected with the issue. 更新2:我简直不敢相信,但这是事实:Apple的SimpleFTPSample也受到该问题的影响。

And here it is - the solution (or rather workaround): 这就是解决方案(或更确切地说,解决方法):

you should set property of writeStream to false, to switch off default persistant connection 您应该将writeStream的属性设置为false,以关闭默认的持久连接

CFWriteStreamSetProperty( (CFWriteStreamRef)writeStreamRef, kCFStreamPropertyFTPAttemptPersistentConnection, kCFBooleanFalse ) ;

Have resolved this error with using operation for request ( NSMutableUrlConnection ) with @autorelease{} for main function 通过将请求操作( NSMutableUrlConnection )与@autorelease{}用于主要功能,已解决了该错误

- (void)main
 NSURLConnection* connection;
    @autoreleasepool //urgently needed for 3G upload
    {

        self.currentRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"test.php"]];
        [self.currentRequest setHTTPMethod:@"PUT"];

        [self.currentRequest setHTTPBody:self.data];//inpustStream doesn't work

        connection = [NSURLConnection connectionWithRequest:self.currentRequest delegate:self];
        [connection start];

    }//end autorelease pool

        do 
        {

            [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]];
            if ([self isCancelled])
            {
                connection          = nil;
                isFailed = YES;
                break;
            }
            self.status(statusUpdateMessage);
        } 
        while (!isFailed && !isCompleted);
        [timer invalidate];//test
        timer = nil;

//corresponding of status via blocks
        self.completed(!isFailed);
        self.status(isFailed ? errorMessage : @"Completed");
        if (isFailed)
        {
            self.failed(errorMessage != nil ? errorMessage : @"Undefined error");
        }

        self.data = nil;
        self.currentRequest = nil;

        connection = nil;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM