Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa NSThread带有_NSAutoreleaseNoPool错误_Cocoa_Multithreading_Memory Management_Memory Leaks - Fatal编程技术网

Cocoa NSThread带有_NSAutoreleaseNoPool错误

Cocoa NSThread带有_NSAutoreleaseNoPool错误,cocoa,multithreading,memory-management,memory-leaks,Cocoa,Multithreading,Memory Management,Memory Leaks,我有一种将文件保存到internet的方法,它可以工作,但速度很慢。然后我想让用户界面更平滑,所以我创建了一个NSThread来处理这个缓慢的任务 我看到的错误列表如下: _NSAutoreleaseNoPool(): Object 0x18a140 of class NSCFString autoreleased with no pool in place - just leaking 如果没有NSThread,我会调用如下方法: [self save:self.savedImg]; 我使

我有一种将文件保存到internet的方法,它可以工作,但速度很慢。然后我想让用户界面更平滑,所以我创建了一个NSThread来处理这个缓慢的任务

我看到的错误列表如下:

_NSAutoreleaseNoPool(): Object 0x18a140 of class NSCFString autoreleased with no pool in place - just leaking
如果没有NSThread,我会调用如下方法:

[self save:self.savedImg];
我使用以下命令来使用NSThread调用该方法:

NSThread* thread1 = [[NSThread alloc] initWithTarget:self
                                        selector:@selector(save:)
                                              object:self.savedImg];
[thread1 start];

谢谢

在线程中,您需要在执行任何其他操作之前创建一个新的自动释放池,否则网络操作将出现您所看到的问题。

您需要主要为线程创建一个自动释放池。尝试将您的保存方法更改为如下所示:

- (void) save:(id)arg {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    //Existing code

    [pool drain];
}

您不会告诉您上述操作没有调用NSAutoreleasePool上的release。这是一个特例。对于NSAutoreleasePool,在没有GC的情况下运行时,drain相当于release,并将其转换为对收集器的提示,提示它可能是运行集合的好时机。

您可能需要创建一个运行循环。我将补充路易斯的解决方案:

BOOL done = NO;

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSRunLoop currentRunLoop];

// Start the HTTP connection here. When it's completed,
// you could stop the run loop and then the thread will end.

do {
    SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
    if ((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished)) {
        done = YES;
    }
} while (!done);

[pool release];

首先,为保存代码创建一个新线程,然后异步使用NSUrlConnection。NSUrlConnection在其自己的实现中还将派生出另一个线程,并调用您新创建的线程,这通常不是您正在尝试做的事情。我想你只是想确保你的UI在保存时不会阻塞

NSUrlConnection还有一个同步版本,它会阻塞你的线程,如果你想启动自己的线程来做事情,最好使用它。签名是

+ sendSynchronousRequest:returningResponse:error:
然后,当您得到响应时,您可以调用回您的UI线程。下面这样的方法应该可以工作:

- (void) beginSaving {
   // This is your UI thread. Call this API from your UI.
   // Below spins of another thread for the selector "save"
   [NSThread detachNewThreadSelector:@selector(save:) toTarget:self withObject:nil];    

}

- (void) save {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  

   // ... calculate your post request...
   // Initialize your NSUrlResponse and NSError

   NSUrlConnection *conn = [NSUrlConnection sendSyncronousRequest:postRequest:&response error:&error];
   // Above statement blocks until you get the response, but you are in another thread so you 
   // are not blocking UI.   

   // I am assuming you have a delegate with selector saveCommitted to be called back on the
   // UI thread.
   if ( [delegate_ respondsToSelector:@selector(saveCommitted)] ) {
    // Make sure you are calling back your UI on the UI thread as below:
    [delegate_ performSelectorOnMainThread:@selector(saveCommitted) withObject:nil waitUntilDone:NO];
   }

   [pool release];
}

我不认为你有任何理由为此使用线程。只要在运行循环中异步执行,就可以在不阻塞UI的情况下工作


信任运行循环。它总是比线程化更容易,并且旨在提供相同的结果(一个永不阻塞的UI)。

同步调用的大小写和签名很接近,应该是NSURLConnection*conn=[NSURLConnection sendSyncronousRequest:postRequest returningResponse:&response error:&error];