ObjCMixin:在 Object-C 裏實現相似 ruby 的 mixin 機制

項目地址:https://github.com/huandu/ObjCMixin
CocoaPods:pod 'ObjCMixin', '~> 0.1.0'git

這是一個腦洞大開的項目……github

原由是我看到了 ObjectiveMixin 項目,它能夠動態的爲 Object-C class 合併其餘 class 的功能,但惋惜不是很完美,主要存在兩個問題:api

  • 沒有相似 ruby 的 mixin 語法,不夠酷炫;
  • Class 的方法修飾其實只是一次性的過程,無需每次 alloc 對象前來作,因此如何可以保證只作一次。

那麼 ObjCMixin 實現了什麼呢?來來來,咱們看看它的威力。ruby

首先,須要聲明一個 module 用來作 mixin。函數

objc// MyModule.h
#import "Mixin.h"

@module(MyModule)
-(void)hello;
@end

實現 module 的函數。code

objc// MyModule.m
#import "MyModule.h"

@module_implementation(MyModule)

-(void)hello
{
    NSLog(@"Hello, mixin!");
}

@end

在一個新的 interface 裏面使用這個 mixin。對象

objc// Foo.h
#import "MyModule.h"

// Foo derives from a special base class.
@interface Foo : NSException<MyModule>
@end

在實現文件裏面將 MyModule 混合到 Foo 裏面。繼承

objc// Foo.m
#import "Foo.h"

@mixin(Foo, MyModule)

@implementation Foo
@end

奇蹟般的,Foo 可使用 MyModule 的全部方法了。ci

objcFoo *f = [[Foo alloc] init];
[f hello]; // Print "Hello, mixin!" in console.

實現方法極度簡單,說出來就會感受很 low。文檔

主要兩點:

  • 用 Object-C runtime api 來複制 class 的方法到另外一個 class,詳見 class_addMethod 的文檔;
  • __attribute__((constructor)) 來聲明一個在 main 以前執行的函數,用來一次性的污染 class 方法,乾淨清晰。

至於有什麼用處?好問題,我還沒想到!

也許這種 mixin 能夠必定程度上知足多繼承的需求,例如某些 category 代碼不方便經過繼承進行耦合,可是代碼自己能夠重複,那能夠考慮一試。

相關文章
相關標籤/搜索