2016-09-30 5 views
4
@interface TestObj :NSObject 
@property(copy, nonatomic)NSString *name; 
@end 
@implementation TestObj 
- (void)testName{ 

    NSLog(@"name:%@",self.name); 

} 
@end 

@interface ViewController() 
@end 

@implementation ViewController 
- (void)viewDidLoad { 

    [super viewDidLoad]; 

    id tclass =[TestObj class]; 

    void * vid = &tclass; 

    [(__bridge id)vid testName]; 

} 
@end 

ログ:iOSのクラスメソッド

私の理解では、なぜ testNameインスタンスメソッドに直接送信することができます vid vidTestObjクラスオブジェクトのアドレスへのポインタです
name: <ViewController: 0x7ff3584b6580> 

さらに、testNameメソッドがNSLogを呼び出す理由が、nilではなく<ViewController: 0x7ff3584b6580>を出力する理由は何ですか?

はありがとうございました。

+0

クラスへのポインタに対してインスタンスメソッドを呼び出すことは本当に奇妙です。 'testName'をインスタンスメソッドではなくクラスメソッドに変更するとどうなるか見てみましょう。 – rmaddy

+0

- [TestObj testName]:インスタンスに送信された認識できないセレクタ – WENHUI

答えて

1

あなたは基本的にあなたがそのコードでクラッシュしていないことを幸運に思っています。

まず、クラスメソッドは+で始まり、-ではないので、これは実装しているインスタンスメソッドです。

@interface TestObj :NSObject 
@property(copy, nonatomic)NSString *name; 
@end 
@implementation TestObj 
+ (void)testName{ 
NSLog(@"name:%@", @"TestObj"); // cannot reference ivars or properties in class method 
} 
@end 
... 
Class classObject = [TestObj class]; 
[classObject testName]; 

クラスオブジェクト(またはインスタンス)へのポインタを取得する必要はありません。 Objective-Cランタイムは、それが属するクラスになる "isa"インスタンス変数を見つけるために、それを与えるポインタを逆参照します。クラスオブジェクトの「isa」はクラスメソッドのリストを含む「メタクラス」です。クラスメソッドのルックアップの仕組みです。あなたの例では、それはポインタを逆参照し、TestObjクラスを見つけます。つまり、TestObjインスタンスでメソッドが呼び出されていないと思います。つまり、割り当てられていませんが、実際はガベージポインタです。しかし、それはまだ(完全な運行によって)インスタンスメソッドの実装に入りますが、 "self"は実際には有効なインスタンスではありません。しかし、値が何であっても、-nameメソッドに応答して、その値を持つNSStringまたはUIViewControllerインスタンス自体を返すようになります。あるいは、ガベージ・ポインタに基づいてインスタンス変数を尊重し、偶然によってViewControllerインスタンスへのポインタで終わるようにしようとしているかもしれません。私は、それは - 名前のメソッドを呼び出すしようとすると思います。

とにかく、あなたのコードはかなり間違っています(&のクラスやインスタンスのポインタを使用しないでください)、あなたはクラッシュしていないのが幸いです。 (ブリッジID)キャストはあなたを助けようとしていた警告を隠しています。

関連する問題