Playing with __attributes__ (二)

canopus4u發表於2015-10-23

objc_boxable

OC可能你經常會看到@(100)等用法。不用奇怪,就是這個Function attributes
使用示例:

struct __attribute__((objc_boxable)) some_struct {
  int i;
};
union __attribute__((objc_boxable)) some_union {
  int i;
  float f;
};
typedef struct __attribute__((objc_boxable)) _some_struct some_struct;

some_struct ss;
NSValue *boxed = @(ss);

objc_requires_super

很多OC的class允許子類過載父類方法,但需要在過載的方法中呼叫父類方法。如:-[UIViewController viewDidLoad],-[UITableViewCell prepareForReuse]等。 對於這樣的情況,objc_requires_super就能派上用場。在父類的方法宣告時使用該屬性,能夠使子類過載方法時必須呼叫父類方法。

- (void)foo __attribute__((objc_requires_super));

Foundation framework已經定義好了一個巨集NS_REQUIRES_SUPER讓開發者使用這個屬性:

- (void)foo NS_REQUIRES_SUPER;

overloadable

使C下的方法呼叫類似C++中的overload:

float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }

呼叫tgsin時會根據引數x型別決定呼叫對應的方法。具體參見C++99標準。不在此贅述。

objc_runtime_name

改變Class或者Protocol的執行時名稱。
(水平有限,暫時不知道有何方便之處)

__attribute__((objc_runtime_name("MyLocalName")))
@interface Message
@end

objc_method_family

先來看一段程式碼:

@interface MyObject: NSObject
@property (nonatomic) newValue;
@end

編譯出現error如下:
Property follows Cocoa naming convention for returning `owned` objects
Explicitly declare getter `-newValue` with `__attribute__((objc_method_family(none)))` to return an `unowned` object

在支援ARC後,clang有一些對於記憶體管理的命名規範。

You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy”

所以,如果方法名以alloc, new, copy, mutableCopy開頭的函式都會被作為生成新物件的函式對返回物件retainCount自增1.
解決辦法為,在property後加入 __attribute__((objc_method_family(none)))

其他用法:

__attribute__((objc_method_family(X)))

X可以是none, alloc, copy, init, mutableCopy, new其中之一。放在property或者函式後面。

當然你也可以使不滿足編譯器命名規則的方法成為生成新物件的方法,如:

- (id) createObject __attribute__((objc_method_family(new)));

下期會介紹剩下的和一些有用的巨集

原作寫於segmentfault 連結

相關文章