実行時にObjective Cオブジェクトにプロパティを追加できますか?実行時にオブジェクトにプロパティを追加するにはどうすればよいですか?
答えて
それはclass_addProperty()
を経由して、クラスに正式なプロパティを追加することが可能です:
BOOL class_addProperty(Class cls,
const char *name,
const objc_property_attribute_t *attributes,
unsigned int attributeCount)
最初の2つのパラメータは自明です。 3番目のパラメータはプロパティの属性の配列で、各プロパティの属性はdeclared propertiesのObjective-C type encodingsに続く名前と値のペアです。ドキュメントでは、プロパティ属性のエンコーディングのカンマ区切り文字列については引き続き記載されています。カンマで区切られた文字列の各セグメントは、objc_property_attribute_t
インスタンスで表されます。さらに、objc_property_attribute_t
は、id
というタイプの汎用コード@
のほかにクラス名を受け入れます。ここで
が動的にすでに_privateName
と呼ばれるインスタンス変数を持つクラスにname
というプロパティを追加し、プログラムの最初のドラフトです:
#include <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject {
NSString *_privateName;
}
@end
@implementation SomeClass
- (id)init {
self = [super init];
if (self) _privateName = @"Steve";
return self;
}
@end
NSString *nameGetter(id self, SEL _cmd) {
Ivar ivar = class_getInstanceVariable([SomeClass class], "_privateName");
return object_getIvar(self, ivar);
}
void nameSetter(id self, SEL _cmd, NSString *newName) {
Ivar ivar = class_getInstanceVariable([SomeClass class], "_privateName");
id oldName = object_getIvar(self, ivar);
if (oldName != newName) object_setIvar(self, ivar, [newName copy]);
}
int main(void) {
@autoreleasepool {
objc_property_attribute_t type = { "T", "@\"NSString\"" };
objc_property_attribute_t ownership = { "C", "" }; // C = copy
objc_property_attribute_t backingivar = { "V", "_privateName" };
objc_property_attribute_t attrs[] = { type, ownership, backingivar };
class_addProperty([SomeClass class], "name", attrs, 3);
class_addMethod([SomeClass class], @selector(name), (IMP)nameGetter, "@@:");
class_addMethod([SomeClass class], @selector(setName:), (IMP)nameSetter, "[email protected]:@");
id o = [SomeClass new];
NSLog(@"%@", [o name]);
[o setName:@"Jobs"];
NSLog(@"%@", [o name]);
}
}
その(トリミング)出力:
Steve
Jobs
getterメソッドとsetterメソッドはより注意深く記述する必要がありますが、実行時に正式なプロパティを動的に追加する方法の例としては十分です。
class_addPropertyはtrueを返しますが、class_getInstanceVariableは常にnilを返します。私はivarの名前の代わりにプロパティ名を入れてみましたが、まだ運がありません。どのような問題が起こる可能性がありますか? – Mercurial
@Bavarious、どうやってコンプライアーを騙しましたか?私は[o name]の結果がコンパイルエラー 'セレクタ' name 'のインスタンスメソッドが見つかりませんでした。 –
@HiteshSavaliya(ARCの前に)これはちょうど可能でした。現在では、少なくとも '-name'セレクタを宣言しなければなりません。 – Michael
@properties - no(ドット構文などを使用)。しかし、関連するオブジェクトを使用してストレージを追加することができます:How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?。
あなたはNSKeyValueCoding
プロトコルを見てみる場合は、あなたが呼ばれるメッセージがあることを確認することができ、hereを文書化:
- (id)valueForUndefinedKey:(NSString *)key
はあなたが指定した未定義のプロパティのカスタム結果を提供するためにそのメソッドをオーバーライドする必要があります。もちろんこれは、あなたのクラスが対応するプロトコルを使用していることを前提としています。
この種のアプローチは、クラス(たとえば、存在しないセレクタ)に未知の動作を提供するために一般的に使用されます。
- 1. 実行時に(app.configではなく)probingPathを追加するにはどうすればよいですか?
- 2. 実行時に複合コントロールをレイアウトに追加するにはどうすればよいですか?
- 3. 実行時にListViewアイテムに動的ビューを追加するにはどうすればよいですか?
- 4. 実行時に新しい列を追加するにはどうすればよいですか?
- 5. UITableViewにオブジェクトを追加するにはどうすればよいですか?
- 6. .netで実行時にオブジェクトにプロパティを追加する方法は?
- 7. IE6のオブジェクトにプロパティを追加するにはどうすればよいですか?
- 8. 実行時にDelphi 2009リボンボタンのcheckedプロパティにアクセスするにはどうすればよいですか?
- 9. ASP.NETコントロール宣言のプロパティに改行を追加するにはどうすればよいですか?
- 10. 実行時にプロパティのTypeConverter属性を変更するにはどうすればよいですか?
- 11. 実行時に(動的に)オブジェクトの特別なプロパティにEditorAttributeを追加する
- 12. コマンドを実行せずにbash履歴に追加するにはどうすればよいですか?
- 13. 実行時に新しいオブジェクトを無制限に追加するにはどうすればよいですか?
- 14. TextBoxに行を追加/削除しないようにするにはどうすればよいですか?
- 15. どのようにC#で実行時にクラスにプロパティを追加できますか?
- 16. App Engineで親オブジェクトに子オブジェクトを追加するにはどうすればよいですか?
- 17. 実行時にリスト<T>にプロパティを追加する
- 18. WHMの実行中にバーチャルホストを正しく追加するにはどうすればよいですか?
- 19. 既存のjavascriptオブジェクトにjavascriptオブジェクトを追加するにはどうすればよいですか?
- 20. コントロールに新しいプロパティを追加するにはどうすればよいですか?
- 21. 既存のxmlファイルに新しいプロパティを追加するにはどうすればよいですか?
- 22. 長時間実行しているGoプログラムを実行するにはどうすればよいですか?
- 23. いくつかのjQueryオブジェクトに関数を追加するにはどうすればよいですか?
- 24. クラスにあるNSMutable配列にオブジェクトを追加するにはどうすればよいですか?
- 25. テーブルに値を追加するにはどうすればよいですか?
- 26. アラートパネルにチェックボックスを追加するにはどうすればよいですか?
- 27. xpathにコメントを追加するにはどうすればよいですか?
- 28. アプリケーションをページに追加するにはどうすればよいですか?
- 29. リクエストにヘッダーフィールドを追加するにはどうすればよいですか?
- 30. テーブルをグラフに追加するにはどうすればよいですか?
KVCプロトコルに準拠している場合 - 可能です – Nekto
プロパティとは正確にはどういう意味ですか? Objective-Cはプロパティを宣言しましたか? –
私は@propertyを意味します – cfischer