Отличие относительно просто.
В состоянии BLOCKED
поток вот-вот войдет в блок synchronized
, но есть еще один поток, текущий в рамках блока synchronized
на тот же объект. Первый поток должен ждать, пока второй поток выйдет из своего блока.
В состоянии WAITING
поток ожидает сигнала из другого потока. Обычно это происходит путем вызова Object.wait()
или Thread.join()
. Затем поток будет оставаться в этом состоянии, пока другой поток не вызовет Object.notify()
или не умрет.
Синхронное NSURLConnection
будет абсолютно работать с NSURLCredentialStorage
. Вот то, как обычно работают вещи:
NSURLConnection
запросы страница с сервера NSURLConnection
надеются видеть, какие учетные данные это может подобрать из URLNSURLConnection
будет также консультироваться NSURLCredentialStorage
для заполнения разрывов -connection:didReceiveAuthenticationChallenge:
метод делегата, просящий учетные данные NSURLConnection
теперь наконец будет иметь полные учетные данные, это повторяет исходный запрос включая данные авторизации. При помощи метода синхронного соединения, Вы только [1 124] терпят неудачу на шаге 5, способность обеспечить пользовательскую аутентификацию. Так, можно или предварительно обеспечить учетные данные аутентификации в URL или разместить их в [1 111] прежде, чем отправить запрос. например,
NSURLRequest *request =
[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://user:pass@example.com"]];
[NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
или:
NSURLCredential *credential = [NSURLCredential credentialWithUser:@"user"
password:@"pass"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:@"example.com"
port:0
protocol:@"http"
realm:nil
authenticationMethod:nil];
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential
forProtectionSpace:protectionSpace];
[protectionSpace release];
NSURLRequest *request =
[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]];
[NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
В ситуации, где 401 или другой запрос аутентификации недопустимо/невозможно, я иногда использую фиктивный CFHTTPMessage для генерации authetication строки, затем копирую тот назад в NSURLRequest:
// assume NSString *username and *password exist and NSURLRequest *urlRequest
// exists and is fully configured except for HTTP Basic Authentication..
CFHTTPMessageRef dummyRequest =
CFHTTPMessageCreateRequest(
kCFAllocatorDefault,
CFSTR("GET"),
(CFURLRef)[urlRequest URL],
kCFHTTPVersion1_1);
CFHTTPMessageAddAuthentication(
dummyRequest,
nil,
(CFStringRef)username,
(CFStringRef)password,
kCFHTTPAuthenticationSchemeBasic,
FALSE);
authorizationString =
(NSString *)CFHTTPMessageCopyHeaderFieldValue(
dummyRequest,
CFSTR("Authorization"));
CFRelease(dummyRequest);
[urlRequest setValue:authorizationString forHTTPHeaderField:@"Authorization"];
Это может казаться полностью причудливым способом сделать это, но это терпимо к ситуациям, где именем пользователя/паролем не является чистый URL и где NSURLRequest отказывается консультироваться с NSURLCredentialStorage, потому что сервер на самом деле не отправляет HTTP 401 (например, это отправляет регулярную страницу вместо этого).
Я отметил бы, что ответ mikeabdullahuk хорош, но также и если Вы будете использовать NSURLCredentialPersistencePermanent вместо на сессию, то это сохранит учетные данные в пользовательской связке ключей в поэтому следующий раз, когда можно проверить NSURLCredentialStorage на не нулевое значение для учетных данных по умолчанию для пространства защиты и если Вы получаете не нулевое значение, можно просто передать учетные данные в. Я использую этот метод прямо сейчас для клиента delicious.com, который я пишу, и он работает очень хорошо в моих тестах.