2014年5月15日 星期四

Class Method (三):Signleton 改 - 在多執行續的解法

在上一篇文章的 Class Method (二):Signleton 有在多執行續使用上的問題,
所以追加教學在多執行續中的 Signleton 的作法。

在舊的 signleton 的作法是這個樣子:
+ (id)method
{
	static Method *singleton = nil;
	if (singleton == nil) {
		singleton = [[Method alloc] init];
	}
	return singleton;
}

這在多執行續之下會有每個執行續都建立一個相同的 signleton 的問題,
所以要避免這個問題,就需要改寫 signleton 的寫法。

新個寫法如下,利用 GCD 的 dispatch_once 的方法來確保,
不管在哪個執行續下都是只有一個 signleton 的物件存在。
+ (id)method
{
	static Method *singleton = nil;
	
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		singleton = [DTFileController new];
	});
	
	return singleton;
}

2014年5月1日 星期四

從圖片檔案讀取 EXIF 資訊

這次是要如何從檔案中讀取一個 EXIF 資訊回來,
EXIF 是保存由相機拍攝下來的資料,
所以通常只要是相機拍的數位相片都有這項資訊,
但是要怎麼取出這些資訊了?
作法請看下面的教學

首先這個教學需要使用 ImageIO 的 framework,所以自己要實作的時候要記得將他 import 進來。

- (NSDictionary *)imagePropertiesWithPath:(NSString *)path
{
	// 將檔案的路徑轉成 NSURL 物件
	NSURL *imageFileURL = [NSURL fileURLWithPath:path];
	// 讀取這個檔案的資訊
	CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
	
	/* 設定準備讀資料的選項,這裡是不要將檔案使用快取的方式,
		這是避免檔案過大,而消耗過多記憶體空間的問題。 */
	NSDictionary *options = @{(id)kCGImageSourceShouldCache: @(NO)};
	
	// 從檔案資訊中擷取關於圖片的資料
	CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options);
	
	CFRelease(imageSource);
	
	return (NSDictionary *)imageProperties;
}

- (void)viewDidLoad
{
	~
	// 取得剛剛的圖片資訊
	NSDictionary *imageProperties = [self imagePropertiesWithPath:_filePath];
	
	// 再從中取出 EXIF 資訊
	NSDictionary *EXIFInformation = imageProperties[(id)kCGImagePropertyExifDictionary];
	
	// 取出 EXIF Auxiliary 資訊
	NSDictionary *EXIFAuxiliary   = imageProperties[(id)kCGImagePropertyExifAuxDictionary];
	
	~
}

這樣子就能取得 EXIF 資訊,另外還有 GPS 資訊也是可以在 imageProperties 中取得,
另外,這次的範例檔:https://github.com/Darktt/EXIF-Reader
範例檔的使用方法,建議使用模擬器,先執行過一次,在 Log 中能找到

**** Directory Path: 

這個資訊,這後面就是接著你要放數位照片的路徑,
請用 Finder 打開這個路徑,放入你要讀取的照片,
重新執行這個程式,這時候就會讀到這張照片的檔名了。