Objective-C の @dynamic
1. @dynamic と @synthesize の違い
@property には、対応する単語が 2 つあり、1 つは @synthesize で、もう 1 つは @dynamic です。 @synthesize も @dynamic も記述されていない場合、デフォルトは @syntheszie です。 var = _var;
@synthesize のセマンティクスは、setter メソッドと getter メソッドを手動で実装しない場合、コンパイラが自動的にこれを追加します。 2つの方法があります。
@dynamic は、プロパティの setter メソッドと getter メソッドがユーザー自身によって実装され、自動的には生成されないことをコンパイラーに伝えます。 (もちろん、読み取り専用プロパティの場合は、getter を指定するだけで済みます)。プロパティが @dynamic var として宣言されており、@setter メソッドと @getter メソッドを提供しない場合、コンパイル時には問題ありませんが、プログラムが instance.var = someVar まで実行されると、プログラムがクラッシュします。 setter メソッドが不足している場合、または someVar = var を実行する場合、getter メソッドが不足しているとクラッシュが発生します。コンパイル時には問題なく、実行時には対応するメソッドが実行されます。これがいわゆる動的バインディングです。
2. プライベート変数を使用して @dynamic アクセス メソッドを実装します
1) Book.h
#import
#import
@インターフェース Book :NSObject
{
@private
__strong NSString *_name;
__strong NSString *_author;
}
@property(nonatomic, copy ) NSString *name;
@property (nonatomic, copy) NSString *author;
@property(nonatomic, copy) NSString*version;
@end
2) Book.m
#import "Book.h"
@implementation Book
@動的名;
@動的著者;
@synthesizeversion = _version;
- (id)init
{
self = [super init];
if(self) {
_name = @"inputbook name を忘れました" } p", _name }
Return _author; 上記のコードからわかるように、@ を使用してください。動的の後、アクセス メソッドでプライベート変数にアクセスして、値を割り当てたり取得したりできます。 。また、 @synthesize は @synthesize var = _var; を直接使用して、属性とプライベート変数を直接同等にします。これが両者の書き方の違いです。
3. メッセージ転送による @dynamic アクセス メソッドの実装
@dynamic var = _var が属性に使用されている場合、コンパイラはすぐにエラーを報告します。このように、@synthesizeのようにvarのsetterメソッドやgetterメソッドで_varを使うことはできません
- (void)setVar:(id)newVar
{
self.var = newVar;
}
- (void)var
{
return self.var;
}
これら 2 つのメソッドは自分自身を呼び出します。これにより、無限ループが発生し、プログラム崩壊。
ここでは、メッセージ転送メカニズムを使用して @dynamic setter メソッドと getter メソッドを実装する方法を示します。
最初のコード:
1) Book.h
#import
@interface Book: NSObject
{
@private
NSMutableDictionary *_propertiesDict;
}
@property (非アトミック、コピー) NSString *name;
@property (非アトミック、コピー) NSString*version; ) Book.h"
@implementation Book
@dynamic name; // name = _name として書くことはできません; そうしないと、コンパイラーはすぐにエラーを報告します
@dynamic author;
@synthesizeversion;
- (id)init
{
self = [スーパー init];
if(self)
{
_propertiesDict = [[NSMutableDictionary alloc] init];
}
return self;
}
- ture *)methodSignatureForSelector:(SEL)selector
{
NSString *sel = NSStringFromSelector(selector);
if ([sel rangeOfString:@"set"].location == 0)
{
return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
}
その他
{
return [NSMethodSignature signatureWithObjCTypes:"@@:"];
}
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
NSString *key = NSStringFromSelector([呼び出しselector]);
if ([key rangeOfString:@"set"].location == 0)
{
key= [[key substringWithRange:NSMakeRange(3, [key length]-4)] lowercaseString];
NSString *obj;
[invocation getArgument:&objatIndex:2];
[_propertiesDict setObject:obj forKey:key];
}
else
{
NSString *obj = [_propertiesDict objectForKey:key] ;
[invocation setReturnValue:&obj];
}
}
@end
3)main.m
#import
#import 「本。 h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
Book *book = [[Book alloc] init];
書籍名= @"c++ 入門書";
book.author = @"Stanley B.Lippman";
book.version = @"5.0";
NSLog(@"%@", book.name);
NSLog (@"%@", book.author);
NSLog(@"%@", book.version);
}
return 0;
}
程序分析:
1)在プログラムはメッセージ送信機能を追加する前に、methodSignatureForSelector: と forwardInvocation: の 2 つのメソッドをカバーする必要があります。methodSignatureForSelector: の機能は、別の種類のメッセージを実現するために有効なメソッド名を作成します。转発行给一个真正实现このメッセージのオブジェクトを完了しました。例 1: - (NSString *)name
このメソッドには 2 つのパラメータがあります: self と_cmd。
例 2: - (void)setValue:(int)val
このメソッドには 3 つのパラメータがあります: self、_cmd および val。
自動的に実現されるメソッドのパラメータ タイプには次のような要求があります:
A. 最初のパラメータ タイプは id (自分自身のタイプ) である必要があります
B. 2 番目のパラメータ タイプSEL (_cmd の種類) である必要があります
C. 3 番目のパラメータから、元のメソッドのパラメータの種類を指定できます。 2 つの例を説明します。
例2: 再比較の場合、setName:(NSString *)name 内のパラメータ名の文字は文字列型であるため、3 番目のパラメータ型は @
3)main.m には、book.name = @"c++ primer";プログラムがここに移動するときに、Book.m 内の setName: このメソッドが存在します。ただし、Book.m にはこのメソッドはありません。このメソッドは、その後、プログラムがmethodSignatureForSelector:に入力してメッセージ送信を実行します。実行が完了すると、メソッドの名前の種類として「v@:@」が返されます。
ここでの v@:@ とは何ですか?実際、ここでの最初の文字 v は、関数の戻り値の型が void であることを表します。次の 3 文字は、上記 2) の説明を参照してください。これらは、self、_cmd、name、の 3 つのパラメータの型です。 id、SEL、NSString。
次に、プログラムは forwardInvocation メソッドに入ります。取得したキーはメソッド名 setName: で、[invocationgetArgument:&objatIndex:2]; を使用してパラメータ値を取得します (ここでは「C++ 入門」)。なぜここのインデックスは 2 である必要があるのでしょうか?前に分析したように、0 番目のパラメータは self、1 番目のパラメータは _cmd、2 番目のパラメータはメソッドの背後にあるパラメータです。
最後に、変数辞書を使用して値を割り当てます。これでセッターのプロセス全体が完了します。
4) main.m には NSLog(@"%@", book.name); というコードがあります。プログラムがここで実行されると、name の値メソッドを見つけるために Book.m に移動します。 。ただし、Book.m にはそのような値メソッドがないため、プログラムは、methodSignatureForSelector: を入力してメッセージを転送します。実行後はメソッドのシグネチャの種類として「@@:」が返されます。ここで、最初の文字 @ は関数の戻り値の型 NSString を表し、2 番目の文字 @ は self の型 ID を表し、3 番目の文字: は _cmd の型 SEL を表します。
次に、プログラムは forwardInvocation メソッドに入ります。取得したキーはメソッド名nameです。最後に、このキーに基づいて辞書から対応する値が取得され、ゲッター プロセス全体が完了します。
5) コードのデバッグのプロセス中に、name と author の割り当てと値のみが、methodSignatureForSelector: と forwardInvocation: の 2 つのメソッドに入力されることが判明したことに注意してください。また、methodSignatureForSelector: と forwardInvocation: の 2 つのメソッドを入力しない属性バージョンもあります。これは、version 属性が @synthesize としてマークされており、コンパイラーが setVersion メソッドと version メソッドを自動的に追加するため、メッセージを転送する必要がないためです。
4. NSManatedObject のサブクラスでの @dynamic の使用
@dynamic の最も一般的な使用は NSManatedObject 内で行われます。現時点では、プログラミングの setter メソッドと getter メソッドを表示する必要はありません。その理由は、@dynamic がコンパイラーに処理を行わないよう指示し、そのゲッター メソッドとセッター メソッドが実行時に動的に作成され、Core Data フレームワークがそのようなプロパティへのアクセス メソッドを生成することを許可するためです。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









機能的特徴: さまざまなシナリオに適したデータ ソースのグループ化、純粋なマルチデータベースの読み取りと書き込みの分離、1 つのマスターと複数のスレーブのハイブリッド モードをサポートします。データ ソースなしの起動と遅延起動データ ソースの構成 (3.3.2 以降) をサポートします。データベースの機密構成情報の暗号化 ENC() をサポートします。各データベースのテーブル構造スキーマとデータベース データベースの独立した初期化をサポートします。カスタム アノテーションをサポートし、DS (3.2.0 以降) を継承する必要があります。 Druid、Mybatis-Plus、P6sy、Jndi の高速統合を提供します。 Druid と HikariCp の構成を簡素化し、グローバル パラメーター構成を提供します。一度設定すれば、それをグローバルに使用できます。カスタマイズされたデータ ソース ソース スキームを提供します。プロジェクトの開始後にデータ ソースを動的に追加および削除するソリューションを提供します。 Mを提供する

Vue.js と Objective-C 言語の統合、信頼性の高い Mac アプリケーションを開発するためのヒントと提案 近年、フロントエンド開発における Vue.js の人気と Mac アプリケーション開発における Objective-C の安定性により、開発者はこの 2 つを組み合わせて、より信頼性が高く効率的な Mac アプリケーションを開発しようとしています。この記事では、開発者が Vue.js と Objective-C を正しく統合し、高品質の Mac アプリケーションを開発するのに役立ついくつかのヒントと提案を紹介します。 1つ

RedisとObjective-Cを使ってキャッシュ予熱機能を開発する方法. インターネットアプリケーションを開発する際、パフォーマンスや応答速度を向上させるために、頻繁にアクセスされるデータを保存するためにキャッシュを使用することが一般的です。キャッシュのウォームアップは一般的な最適化戦略であり、人気のあるデータを事前にキャッシュにロードすることで、ユーザーが初めてアクセスするときの待ち時間を回避できます。この記事では、Redis と Objective-C を使用してキャッシュ予熱機能を開発する方法と、具体的なコード例を紹介します。 1. RedisRedi の概要

Vue.js と Objective-C を使用して革新的な iOS アプリ エクスペリエンスを開発する方法 Vue.js は、ユーザー インターフェイスの構築に重点を置いた人気のある JavaScript フレームワークです。 Objective-C は、iOS アプリケーション開発の主流のプログラミング言語です。この記事では、Vue.js と Objective-C を併用して革新的な iOS アプリケーション エクスペリエンスを開発する方法を紹介し、コード例を示します。環境の準備 まず、次の環境をインストールして構成する必要があります。

Vue.js と Objective-C 言語の統合、iOS アプリケーション開発のベスト プラクティス 今日のモバイル アプリケーション開発の分野では、iOS システムは常に最も人気のあるプラットフォームの 1 つです。 Objective-C 言語は、iOS アプリケーションの主要な開発言語として、さまざまな iOS アプリケーションの開発で広く使用されています。ただし、開発プロセスでは、ユーザー インターフェイスをより適切に構築し、データを処理するために、フロントエンド フレームワークを使用する必要があることがよくあります。 Vue.js は人気のある JavaScript フレームワークです。

Vue.js と Objective-C を使用してスケーラブルな iOS アプリケーションを作成する方法 はじめに: 進化し続けるモバイル アプリケーション開発分野に直面して、適切なテクノロジ スタックを選択することは開発者にとって特に重要です。 Vue.js は、ユーザー インターフェイスの構築に使用できる人気のある JavaScript フレームワークです。 Objective-C は、オブジェクト指向プログラミング言語として、iOS アプリケーション開発に推奨される言語です。この記事ではVue.jsとObjective-Cを使った書き方を紹介します。

Redis と Objective-C を使用してリアルタイムの地理位置追跡を開発する方法 地理位置追跡は、リアルタイムの位置共有、タクシー配車アプリ、ソーシャル メディアなど、多くのアプリケーションに不可欠な部分になっています。モバイル アプリケーションにリアルタイムの地理位置情報追跡を実装するには、データ ストレージ、位置情報サービス、データ同期の問題など、多くの課題に直面します。 Redis と Objective-C は、これらの課題の解決に役立つ 2 つの非常に人気のあるツールです。この記事ではRediの使い方を紹介します。

Vue.js と Objective-C 言語の統合、信頼性の高い Mac アプリケーションを開発するためのヒントと開発経験の共有 はじめに: 今日、Web アプリケーションの開発はますます人気が高まっており、Vue.js フレームワークは最高のフレームワークの 1 つです。ただし、場合によっては、Objective-C 言語との統合を通じて信頼性の高い Mac アプリケーションを開発する必要があるかもしれません。この記事では、Ma を正常に完了するために役立つ、Vue.js と Objective-C 言語の統合に関するヒントと開発経験を共有します。
