2016-04-20 6 views
1

よく知られていて非特異的な診断を受けています:「表示されない@interface for ...セレクタを宣言しています...」この診断はこのサイトに何度も現れた(私はそれらのほとんどを見てきましたが)提案された修正のどれも私の場合には関係していないようです。ありがとう!Objective-Cクラスがヘルパーメソッドに応答できません

私はマウスを使ってOpenGLサーフェスを回転させる古いCocoaプログラムを持っています。 (古いAppleのデモであるNSGL Teapotに基づいています)。サーフェスはNSOpenGLView(Class SurfaceView)で作成され、回転を実行するためのコードはTrackballというヘルパークラスにあります。マウスが画面上で「スライド」すると、Trackballインスタンスのメソッド(rollToと呼ばれる)が回転量を提供するSurfaceViewのメソッド(rotateByと呼ばれる)を呼び出します。残念ながら、Xcode 7.3は、NSOpenGLViewがrotateByセレクタ(メソッド)のための目に見えるインターフェースを欠いていると訴えています。

コードは15年前に完全にコンパイルされましたが、現在ではありません。プログラム内の他のすべてが正常に動作します(サーフェスがレンダリングされ、さまざまなスライダなどに正しく応答します)。どのようにしてOpenGLビューをrotateByに返すことができますか?

ありがとうございました!

ここインタフェース(4つのスペースをインデント)

#import <Cocoa/Cocoa.h> 
#import <OpenGL/OpenGL.h> 
#import <OpenGL/gl.h> 
#import <OpenGL/glu.h> 
#import <GLUT/glut.h> 
#import "Trackball.h" 
@interface SurfaceView : NSOpenGLView 
{ 
    float width; 
    GLUnurbsObj *theNurb; 
    Trackball *m_trackball; 
    // The main rotation 
    float m_rotation[4]; 
    // The trackball rotation 
    float m_tbRot[4]; 
} 
- (id)initWithFrame:(NSRect)frameRect; 
- (void)drawRect:(NSRect)rect; 
- (void)rotateBy:(float *)r; 
- (void)mouseDown:(NSEvent *)theEvent; 
- (void)mouseUp:(NSEvent *)theEvent; 
- (void)mouseDragged:(NSEvent *)theEvent; 
- (void)zeroRotate; 
@end 

メソッド体である:

- (void)rotateBy:(float *)r 
{ 
     m_tbRot[0] = r[0]; 
     m_tbRot[1] = r[1]; 
     m_tbRot[2] = r[2]; 
     m_tbRot[3]= r[3]; 
} 

ここでは、エラーが発生した方法である。

- (void)rollTo:(NSPoint)pt sender:(NSOpenGLView *)sender 
{ 
    float xxyy; 
    float rot[4]; 
    float cosAng, sinAng; 
    float ls, le, lr; 

    m_endPt[0] = pt.x - m_ctr.x; 
    m_endPt[1] = pt.y - m_ctr.y; 
    if (fabs(m_endPt[0] - m_startPt[0]) < kTol && fabs(m_endPt[1] - m_startPt[1]) < kTol) 
     return; // Not enough change in the vectors to have an action. 

    // Compute the ending vector from the surface of the ball to its center. 
    xxyy = m_endPt[0]*m_endPt[0] + m_endPt[1]*m_endPt[1]; 
    if (xxyy > m_radius*m_radius) { 
     // Outside the sphere. 
     m_endPt[2] = 0.; 
    } else 
     m_endPt[2] = sqrt(m_radius*m_radius - xxyy); 

    // Take the cross product of the two vectors. r = s X e 
    rot[1] = m_startPt[1] * m_endPt[2] - m_startPt[2] * m_endPt[1]; 
    rot[2] = -m_startPt[0] * m_endPt[2] + m_startPt[2] * m_endPt[0]; 
    rot[3] = m_startPt[0] * m_endPt[1] - m_startPt[1] * m_endPt[0]; 

    // Use atan for a better angle. If you use only cos or sin, you only get 
    // half the possible angles, and you can end up with rotations that flip around near 
    // the poles. 

    // cos(a) = (s . e)/(||s|| ||e||) 
    cosAng = m_startPt[0]*m_endPt[0] + m_startPt[1]*m_endPt[1] + m_startPt[2]*m_endPt[2]; // (s . e) 
    ls = sqrt(m_startPt[0]*m_startPt[0] + m_startPt[1]*m_startPt[1] + m_startPt[2]*m_startPt[2]); 
    ls = 1./ls; // 1/||s|| 
    le = sqrt(m_endPt[0]*m_endPt[0] + m_endPt[1]*m_endPt[1] + m_endPt[2]*m_endPt[2]); 
    le = 1./le; // 1/||e|| 
    cosAng = cosAng * ls * le; 

    // sin(a) = ||(s X e)||/(||s|| ||e||) 
    sinAng = lr = sqrt(rot[1]*rot[1] + rot[2]*rot[2] + rot[3]*rot[3]); // ||(s X e)||; 
           // keep this length in lr for normalizing the rotation vector later. 
    sinAng = sinAng * ls * le; 
    rot[0] = (float)atan2(sinAng, cosAng) * kRad2Deg; // GL rotations are in degrees. 

    // Normalize the rotation axis. 
    lr = 1./lr; 
    rot[1] *= lr; rot[2] *= lr; rot[3] *= lr; 

    [sender rotateBy:rot]; 
} 
+0

あなたは、問題のメソッドとクラスのメソッド定義とインタフェースを共有することはできますか? – NSNoob

+0

申し訳ありませんが、私はちょっと新しいです - どこにコードを入力しますか? –

+0

問題ありません。ようこそ。質問を編集して関連するコードを追加するだけです。必要に応じて、私や他のコミュニティーメンバーがフォーマットを担当します。 – NSNoob

答えて

1

場合にrotateBy:と電話したいメソッドのシグネチャには、そのメソッドを実装するsenderが必要です。

それ書き換えなど:

- (void)rollTo:(NSPoint)pt sender:(SurfaceView *)sender 

またsenderにキャストを使用することができますが、それはもっと危険です。コンパイラの代わりに実行時エラーが発生する可能性があります。

1

使用方法が間違っています。これはおそらく常に間違っていました。コンパイラだけがそれをよりよく検出しています。

senderNSOpenGLViewと宣言されており、rotateBy:メソッドが呼び出されています。 NSOpenGLViewにはそのようなメソッドはありません。このメソッドを持つのはサブクラスSurfaceViewです。

単純な解決策の1つは、型情報を完全に削除するためにsenderidと宣言することです。

senderパラメータを正しくSurfaceViewと宣言することをお勧めします。

あなたが同じインターフェイスを維持する必要がある場合は、単にキャストを実行

[(SurfaceView *) sender rotateBy:rot]; 
+0

素晴らしい!ありがとう、キャストは完璧に働いた。どうもありがとう!! –

+1

SulthanとPhillip Mills(と他の人)に、Cocoaのクエリに対する非常に有益な回答に感謝します。このサイトの優れた有用性を非常にうまく示しています! –