Swift 2.x ответ, который загружает изображение в файл (в отличие от ответа Лео Дабуса, в котором хранится изображение в памяти). На основании ответа Льва Дабуса и ответа Роба из Получить данные из NSURLSession DownloadTaskWithRequest из обработчика завершения :
// Set download vars
let downloadURL = NSURL() // URL to download from
let localFilename = "foobar.png" // Filename for storing locally
// Create download request
let task = NSURLSession.sharedSession().downloadTaskWithURL(downloadURL) { location, response, error in
guard location != nil && error == nil else {
print("Error downloading message: \(error)")
return
}
// If here, no errors so save message to permanent location
let fileManager = NSFileManager.defaultManager()
do {
let documents = try fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
let fileURL = documents.URLByAppendingPathComponent(localFilename)
try fileManager.moveItemAtURL(location!, toURL: fileURL)
self.doFileDownloaded(fileURL, localFilename: localFilename)
print("Downloaded message @ \(localFilename)")
} catch {
print("Error downloading message: \(error)")
}
}
// Start download
print("Starting download @ \(downloadURL)")
task.resume()
// Helper function called after file successfully downloaded
private func doFileDownloaded(fileURL: NSURL, localFilename: String) {
// Do stuff with downloaded image
}
Пространства имен являются пакетами по существу. Они могут использоваться как это:
namespace MyNamespace
{
class MyClass
{
};
}
Тогда в коде:
MyNamespace::MyClass* pClass = new MyNamespace::MyClass();
Hope, которая помогает.
Или, если Вы хотите всегда использовать определенное пространство имен, можно сделать это:
using namespace MyNamespace;
MyClass* pClass = new MyClass();
Редактирование: После того, что сказал bernhardrusch, я склонен не использовать "синтаксис" пространства имен x использования вообще, я обычно явно определяю пространство имен при инстанцировании моих объектов (т.е. первый пример, который я показал).
И поскольку Вы спросили ниже , можно использовать столько пространств имен, сколько Вам нравится.
Другое различие между Java и C++, то, что в C++, иерархии пространства имен не нужно Маху расположение файловой системы. Таким образом, я склонен помещать всю допускающую повторное использование библиотеку в единое пространство имен и подсистемы в библиотеке в подкаталогах:
#include "lib/module1.h"
#include "lib/module2.h"
lib::class1 *v = new lib::class1();
я только поместил бы подсистемы во вложенные пространства имен, если бы была возможность конфликта имен.
Я использовал пространства имен C++ тем же путем, я делаю в C#, Perl, и т.д. Это - просто семантическое разделение символов между стандартным материалом библиотеки, сторонним материалом и моим собственным кодом. Я поместил бы свое собственное приложение в одно пространство имен, затем допускающий повторное использование компонент библиотеки в другом пространстве имен для разделения.
Обратите внимание, что пространство имен в C++ действительно является просто пространством имен. Они не обеспечивают ни одной инкапсуляции, которую пакеты делают в Java, таким образом, Вы, вероятно, не будете использовать их как очень.
Я предпочитаю использовать пространство имен верхнего уровня для приложения и sub пространства имен для компонентов.
способ, которым можно использовать классы от других пространств имен, удивительно очень похож на путь в Java. Можно или использовать "ПРОСТРАНСТВО ИМЕН использования", которое подобно "оператору" ПАКЕТА импорта, например, используйте станд., Или Вы определяете пакет как префикс класса, разделенного с "::", например, станд.:: строка. Это подобно "java.lang. Строка" в Java.
Вообще говоря, я создаю пространство имен для тела кода, если я полагаю, что могло бы возможно быть имя функции или конфликты имени типа с другими библиотеками. Это также помогает выпустить под брендом код, крыло повышение:: .
Да, можно использовать несколько пространств имен за один раз, например:
using namespace boost;
using namespace std;
shared_ptr<int> p(new int(1)); // shared_ptr belongs to boost
cout << "cout belongs to std::" << endl; // cout and endl are in std
[февраль 2014 - (Это действительно было это долго?): Этот конкретный пример теперь неоднозначен, как Joey указывает ниже. Повышение и станд.:: теперь у каждого есть shared_ptr.]
Можно также содержать "пространство имен использования..." в функции, например:
void test(const std::string& s) {
using namespace std;
cout << s;
}
Кроме того, обратите внимание, что можно добавить к пространству имен. Это более ясно с примером, что я имею в виду, то, что Вы можете иметь:
namespace MyNamespace
{
double square(double x) { return x * x; }
}
в файле square.h
, и
namespace MyNamespace
{
double cube(double x) { return x * x * x; }
}
в файле cube.h
. Это определяет единое пространство имен MyNamespace
(то есть, можно определить единое пространство имен через несколько файлов).
Большие проекты C++ я видел едва используемый больше чем одно пространство имен (например, стимулируйте библиотеку).
На самом деле повышение использует тонны пространств имен, обычно каждая часть повышения имеет свое собственное пространство имен для внутренних работ и затем может поместить только открытый интерфейс в повышение пространства имен верхнего уровня.
Лично я думаю что, чем больше кодовая база становится, тем более важные пространства имен становятся, даже в рамках отдельного приложения (или библиотека). На работе мы помещаем каждый модуль нашего приложения в его собственном пространстве имен.
Другое использование (никакая предназначенная игра слов) пространств имен, что я использую много, является анонимным пространством имен:
namespace {
const int CONSTANT = 42;
}
Это - в основном то же как:
static const int CONSTANT = 42;
Используя анонимное пространство имен (вместо помех) однако рекомендуемый путь к коду и данным, чтобы быть видимым только в текущей единице компиляции в C++.
Не слушайте каждый люди, говорящие Вам, что пространства имен являются просто пространствами имен.
Они важны, потому что они, как полагает компилятор, применяют интерфейсный принцип. В основном это может быть объяснено примером:
namespace ns {
class A
{
};
void print(A a)
{
}
}
, Если бы Вы хотели распечатать объект, код был бы этим:
ns::A a;
print(a);
Примечание, что мы явно не упоминали пространство имен при вызывании функции. Это - интерфейсный принцип: C++ рассматривает функцию, берущую тип в качестве аргумента, как являющегося частью интерфейса для того типа, таким образом, никакая потребность определить пространство имен, потому что параметр уже подразумевал пространство имен.
Теперь, почему этот принцип важен? Предположите, что автор класса A не обеспечил печать () функция для этого класса. Необходимо будет обеспечить тот сами. Поскольку Вы - хороший программист, Вы определите эту функцию в своем собственном пространстве имен, или возможно в глобальном пространстве имен.
namespace ns {
class A
{
};
}
void print(A a)
{
}
И Ваш код может начать называть печать (a) функцией везде, где Вы хотите. Теперь предположите, что несколько лет спустя, автор решает обеспечить печать () функция, лучше, чем Ваш, потому что он знает внутренности своего класса и может сделать лучшую версию, чем Ваш.
Тогда авторы C++ решили, что его версия печати () функция должна использоваться вместо той, обеспеченной в другом пространстве имен, для соблюдения интерфейсного принципа. И что это "обновление" печати () функция должна быть максимально легкой, что означает, что Вы не должны будете изменять каждый вызов на печать () функция. Вот почему "функции интерфейса" (функция в том же пространстве имен как класс) можно назвать, не определяя пространство имен в C++.
И вот почему необходимо рассмотреть пространство имен C++ как "интерфейс", когда Вы используете один и имеете в виду интерфейсный принцип.
, Если Вы хотите лучшее объяснение этого поведения, можно отослать к книге Исключительный C++ от Herb Sutter
Vincent Robert прав в своем комментарии , Как Вы правильно используете пространства имен в C++? .
используются по крайней мере, чтобы помочь избежать коллизии имени. В Java это осуществляется через "org.domain" идиому (потому что предполагается, что каждый не будет использовать ничто больше, чем его собственное доменное имя).
В C++, Вы могли дать пространство имен всему коду в Вашем модуле. Например, для модуля MyModule.dll, Вы могли дать его коду пространство имен MyModule. Я имею, посмотрите в другом месте кого-то использование MyCompany:: MyProject:: MyModule. Я предполагаю, что это - излишество, но в целом, это кажется корректным мне.
Используя должен использоваться с большой осторожностью, потому что это эффективно импортирует один (или все) символы от пространства имен в Ваше текущее пространство имен.
Это является злым, чтобы сделать это в заголовочном файле, потому что Ваш заголовок загрязнит каждый источник включая его (это напоминает мне о макросах...), и даже в исходном файле, плохо разработайте вне функционального объема, потому что это импортирует в глобальной области видимости символы от пространства имен.
самый безопасный способ использовать "использование" состоит в том, чтобы импортировать избранные символы:
void doSomething()
{
using std::string ; // string is now "imported", at least,
// until the end of the function
string a("Hello World!") ;
std::cout << a << std::endl ;
}
void doSomethingElse()
{
using namespace std ; // everything from std is now "imported", at least,
// until the end of the function
string a("Hello World!") ;
cout << a << endl ;
}
Вы будете видеть большое "использование станд. пространства имен"; в учебном руководстве или примерах кода. Причина состоит в том, чтобы сократить количество символов для создания чтения легче, не потому что это - хорошая идея.
"станд. пространства имен использования"; препятствуется Scott Meyers (я не помню точно, какую книгу, но я могу найти им при необходимости).
Пространства имен являются больше, чем пакеты. Другой пример может быть найден в Bjarne Stroustrup "Язык Программирования на C++".
В "Специальном выпуске", по телефону 8.2.8 Состав Пространства имен, он описывает, как можно объединить два пространства имен AAA и BBB в другой названный CCC. Таким образом CCC становится псевдонимом и для AAA и для BBB:
namespace AAA
{
void doSomething() ;
}
namespace BBB
{
void doSomethingElse() ;
}
namespace CCC
{
using namespace AAA ;
using namespace BBB ;
}
void doSomethingAgain()
{
CCC::doSomething() ;
CCC::doSomethingElse() ;
}
Вы могли даже импортировать избранные символы из различных пространств имен, для создания собственного интерфейса пространства имен. Я должен все же найти практическое применение этого, но в теории, это прохладно.
Чтобы постараться не говорить все, Mark Ingram уже сказал немного подсказки для использования пространств имен:
Избегают "директивы" пространства имен использования в заголовочных файлах - это открывает пространство имен для всех частей программы, которые импортируют этот заголовочный файл. В файлах реализации (*.cpp) это обычно не большая проблема - хотя я предпочитаю использовать "директиву" пространства имен использования по функциональному уровню.
я думаю, что пространства имен главным образом используются для предотвращения конфликтов имен - не обязательно для организации структуры кода. Я организовал бы программы C++ главным образом с заголовочными файлами / файловая структура.
Иногда пространства имен используются в больших проектах C++ скрыть детали реализации.
Дополнительное примечание к директиве использования: Некоторые люди предпочитают использовать "использование" только для единственных элементов:
using std::cout;
using std::endl;
В Java:
package somepackage;
class SomeClass {}
В C++:
namespace somenamespace {
class SomeClass {}
}
И использование их, Java:
import somepackage;
И C++:
using namespace somenamespace;
кроме того, полные имена "somepackge. SomeClass" для Java и "somenamespace:: SomeClass" для C++. Используя те соглашения, можно организовать как Вы, привыкли к в Java, включая создание соответствия именам папок для пространств имен. Папка-> пакет и файл-> требования класса не там, хотя, таким образом, можно назвать папки и классы независимо от пакетов и пространств имен.
Я не видел упоминания об этом в других ответах, поэтому вот мои 2 канадских цента:
В теме «Использование пространства имен» полезным утверждением является псевдоним пространства имен, позволяя вам «переименовать» пространство имен, как правило, чтобы дать ему более короткое имя. Например, вместо:
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::TheClassName foo;
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::AnotherClassName bar;
вы можете написать:
namespace Shorter = Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally;
Shorter::TheClassName foo;
Shorter::AnotherClassName bar;