[筆記] Waht's New in Objective-C and Foundation in iOS 7

Modules

在舊的架構下,iOS會幫你每個UI檔案(ex. UIViewController ...etc.) import UIkit.h這個檔案,很不幸的這個檔案有超過11,000行程式碼,這意味著你每個檔案都會至少大於11,000行,那不是肥慘了!!

Original solution: Pre-compiled headers

原有的解法是依靠pre-compiled把需要用的東西cache起來,如下面這段:

#import <Availability.h>
 
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
 
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif

New solution: Modules

每一次你用新的framework系統就自動幫你執行下面的動作:

  1. Add #import line to the file using the framework
  2. Write code that uses the framework.
  3. Compile.
  4. Watch as errors are spat out during linking.
  5. Remember that you forgot to link the framework.
  6. Add the linking of the framework to the project build phase.
  7. Compile again.

如何使用


除此之外,Module還自動幫你把#import轉成@import

BUT! Modules 並不支援任何第三方frameworks,所以沒事暫時不要啟用這個功能吧。

New Foundations

NSArray

NSArray *array = @[@"A", @"B", @"C"];
NSString *firstString = [array firstObject];
NSString *lastString = [array lastObject];

NSTimer

大意是,藉由設定tolerance改善task群組的方式,改進iOS對NSTimer的效率。

- (NSTimeInterval)tolerance;
- (void)setTolerance:(NSTimeInterval)tolerance;

NSProgress

假設你有10個任務,要每完成一個就回報給Progress更新,也許你會用Key value Observing (KVO) 去觀察 NSProgress 的實體,然後通知progress bar更新,更新prgress bar的進度與文字。

Reporting progress

+ (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount;
NSArray *array = /* ... */;
 
NSProgress *progress = 
    [NSProgress progressWithTotalUnitCount:array.count];
 
[array enumerateObjectsUsingBlock:
    ^(id obj, NSUInteger idx, BOOL *stop) {
        // Perform an expensive operation on obj
        progress.completedUnitCount = idx;
    }];

Receiving progress updates

@property (readonly) double fractionCompleted;

當fractionCompleted從0變成1的時候,表示所有任務都已經完成,這非常適合用KVO去觀察這個property:

[_progress addObserver:self 
            forKeyPath:@"fractionCompleted" 
               options:NSKeyValueObservingOptionNew 
               context:NULL];

接著, override通知的method

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
    if (object == _progress) {
        // Handle new fractionCompleted value
        return;
    }
 
    // Always call super, incase it uses KVO also
    [super observeValueForKeyPath:keyPath 
                         ofObject:object 
                           change:change 
                          context:context];
}

別忘了移除KVO免得造成crash

[_progress removeObserver:self 
               forKeyPath:@"fractionCompleted" 
                  context:NULL];

後記

有些東西還是看不太懂阿(汗),不過還是硬著頭皮硬翻,如有錯誤請大大門指正,感激不盡。

Refernce