iOS - 面向切面編程(AOP)

AOP: Aspect Oriented Programming 面向切面編程git

1、什麼是AOP

  • 經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術
  • AOP是OOP的延續,函數式編程的一種衍生範型

2、AOP的優點

  • 對業務邏輯的各個部分進行隔離
  • 下降業務邏輯各部分之間的耦合度
  • 提升程序的可重用性
  • 提升了開發的效率

3、AOP在iOS的應用 - runtime

利用iOS的runtime,咱們能夠作不少移花接木的事情,讓人首先聯想到的就是Method Swizzle,對於Method Swizzle,這裏不展開描述,有興趣的能夠自行深刻了解github

Aspects

一個使用起來簡單愉快的iOS AOP 庫objective-c


(一)基本用法

+ (id<AspectToken>)aspect_hookSelector:(SEL)selector
                           withOptions:(AspectOptions)options
                            usingBlock:(id)block
                                 error:(NSError **)error;

- (id<AspectToken>)aspect_hookSelector:(SEL)selector
                           withOptions:(AspectOptions)options
                            usingBlock:(id)block
                                 error:(NSError **)error;
複製代碼

AspectPositions編程

typedef NS_OPTIONS(NSUInteger, AspectOptions) {
    AspectPositionAfter   = 0,            // 在原始實現後調用(default)
    AspectPositionInstead = 1,            // 將替換原始實現
    AspectPositionBefore  = 2,            // 在原始實現以前調用
    AspectOptionAutomaticRemoval = 1 << 3 // 執行一次後移除Hook
};
複製代碼

AspectInfoasync

@protocol AspectInfo <NSObject>
- (id)instance;

- (NSInvocation *)originalInvocation;

- (NSArray *)arguments;
@end
複製代碼

(二)Aspects 埋點實戰

/** 統計頁面的訪問量 */
    [UIViewController aspect_hookSelector:@selector(viewDidAppear:)
                              withOptions:AspectPositionAfter
                               usingBlock:^(id<AspectInfo> aspectInfo){
                                   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                                       NSString *className = NSStringFromClass([[aspectInfo instance] class]);
                     [self doSomething];
                                   });
                               } error:NULL];
複製代碼

(三)使用注意

  • Aspects 使用了Objective-C 的消息轉發機會,會有必定的性能消耗,全部對於過於頻繁的調用,不建議使用 Aspects
  • 當應用於某個類時(使用類方法添加鉤子),不能同時hook父類和子類的同一個方法,不然會引發循環調用問題;可是當應用於某個類的示例時(使用實例方法加鉤子),不受此限制。
  • 使用KVO時,最好在 aspect_hookSelector: 調用以後添加觀察者,不然可能會引發崩潰
相關文章
相關標籤/搜索