Из Bjarne Stroustrup C ++ 0x FAQ :
__cplusplus
В C ++ 0x макрос
blockquote>__cplusplus
будет установлено значение, которое отличается от (больше) текущего199711L
.Хотя это не так полезно, как хотелось бы.
gcc
(видимо, в течение почти 10 лет) это значение было установлено на1
, исключая один главный компилятор, до тех пор, пока он не был зафиксирован, когда gcc 4.7.0 вышел .Это стандарты C ++ и какое значение вы должны ожидать в
__cplusplus
:
- C ++ pre-C ++ 98:
__cplusplus
is1
.- C ++ 98:
__cplusplus
is199711L
.- C ++ 98 + TR1: Это читается как C ++ 98, и нет способа проверить, что я знаю.
- C ++ 11:
__cplusplus
is201103L
.- C ++ 14:
__cplusplus
is201402L
.- C ++ 17 :
__cplusplus
is201703L
.Если компилятор может быть старше
gcc
, нам нужно обратиться к специфическому хакерству компилятора (посмотрите на макрос версии, сравните его с таблица с реализованными функциями) или используйте Boost.Config (который предоставляет соответствующие макросы ). Преимущество этого в том, что мы действительно можем выбрать конкретные функции нового стандарта и написать обходное решение, если эта функция отсутствует. Это часто предпочтительнее для оптового решения, так как некоторые компиляторы будут требовать реализовать C ++ 11, но предлагают только набор функций.В Stdcxx Wiki размещена всеобъемлющая матрица для поддержки компилятора из функций C ++ 0x (если вы решились проверить сами функции).
К сожалению, более мелкозернистая проверка функций (например, отдельные функции библиотеки, такие как
std::copy_if
) может выполняться в системе сборки вашего приложения (запустить код с помощью функции, проверить, скомпилирован ли он и получить правильные результаты -autoconf
является инструментом выбора при прохождении этого маршрута).
Я создал приложение такого типа, используя приблизительно тот же подход, за исключением:
UIImage
, а рисую изображение в слое, когда масштабирование равно 1. Эти плитки будут автоматически высвобождаться при выдаче предупреждений памяти. Всякий раз, когда пользователь начинает масштабирование, я получаю CGPDFPage
и отображаю его, используя соответствующий CTM. Код в - (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context
похож на:
CGAffineTransform currentCTM = CGContextGetCTM(context);
if (currentCTM.a == 1.0 && baseImage) {
//Calculate ideal scale
CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width;
CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height;
CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight);
CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor);
CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height);
CGContextDrawImage(context, imageRect, [baseImage CGImage]);
} else {
@synchronized(issue) {
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1);
pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true);
CGContextConcatCTM(context, pdfToPageTransform);
CGContextDrawPDFPage(context, pdfPage);
}
}
проблема - объект, связывающийся с CGPDFDocumentRef
. Я синхронизирую часть, где я получаю доступ к свойству pdfDoc
, потому что я освобождаю его и воссоздаю его при получении memoryWarnings. Кажется, что объект CGPDFDocumentRef
выполняет некоторое внутреннее кэширование, от которого я не нашел, как избавиться.
Для простого и эффективного средства просмотра PDF, когда вам требуется только ограниченная функциональность, вы можете (iOS 4.0+) использовать платформу QuickLook:
Во-первых, вам нужно связать ссылки с QuickLook.framework
и #import
<QuickLook/QuickLook.h>;
Впоследствии либо в viewDidLoad
, либо в любом из ленивых методов инициализации:
QLPreviewController *previewController = [[QLPreviewController alloc] init];
previewController.dataSource = self;
previewController.delegate = self;
previewController.currentPreviewItemIndex = indexPath.row;
[self presentModalViewController:previewController animated:YES];
[previewController release];
CGAffineTransform currentCTM = CGContextGetCTM(context); if
(currentCTM.a == 1.0 && baseImage) {
//Calculate ideal scale
CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width;
CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height;
CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight);
CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor,
baseImage.size.height/imageScaleFactor);
CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2,
(self.bounds.size.height-imageSize.height)/2, imageSize.width,
imageSize.height);
CGContextDrawImage(context, imageRect, [baseImage CGImage]); } else {
@synchronized(issue) {
CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1);
pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true);
CGContextConcatCTM(context, pdfToPageTransform);
CGContextDrawPDFPage(context, pdfPage);
} }
Начиная с iOS 11 , вы можете использовать собственный фреймворк под названием PDFKit для отображения и управления PDF-файлами.
После импорта PDFKit вы должны инициализировать PDFView
локальным или удаленным URL-адресом и отобразить его в своем представлении.
if let url = Bundle.main.url(forResource: "example", withExtension: "pdf") {
let pdfView = PDFView(frame: view.frame)
pdfView.document = PDFDocument(url: url)
view.addSubview(pdfView)
}