1

このコードを手に入れました:

#import <Foundation/Foundation.h>
@interface CalculatorBrain : NSObject
- (void)pushOperand:(double)operand;
- (double)performOperation:(NSString *)op;
@property (nonatomic, readonly) id program;
+ (NSString *)descriptionOfProgram:(id)program;
+ (double)runProgram:(id)program;
@end

そしてこれ:

#import "CalculatorBrain.h"
@interface CalculatorBrain()
@property (nonatomic, strong) NSMutableArray *programStack;
@end
@implementation CalculatorBrain
@synthesize programStack = _programStack;
- (NSMutableArray *)programStack
{
if (_programStack == nil) _programStack = [[NSMutableArray alloc] init];
return _programStack;
}
- (id)program
{
return [self.programStack copy];
}
+ (NSString *)descriptionOfProgram:(id)program
{
return @"blablabla";
}
    - (void)pushOperand:(double)operand
{
   [self.programStack addObject:[NSNumber numberWithDouble:operand]];
}

- (double)performOperation:(NSString *)operation
{
[self.programStack addObject:operation];
return [[self class] runProgram:self.program];
}

+ (double)popOperandOffProgramStack:(NSMutableArray *)stack
{
   double result = 0;
   return result;
}
+ (double)runProgram:(id)program
{
   NSMutableArray *stack;
   if ([program isKindOfClass:[NSArray class]]) {
      stack = [program mutableCopy];
   }
   return [self popOperandOffProgramStack:stack];
}
@end

コードは問題なく実行されるので、問題は、インターフェイスのどこでpopOperandOffProgramStackが宣言されているかということです。なぜコンパイルして大丈夫なのですか?クラッシュするはずですが、説明が見つかりません。

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

4

2 に答える 2

2

@interfaceメソッドを世界に公開する場合にのみ、.hファイルでメソッドを宣言する必要があります。それ以外の場合、宣言は必要ありません。

そして今日では、それらが実装に現れる順序も重要ではありません。歴史的に、メソッド@implementationが呼び出された場所よりも後で実装された場合は、メソッドを上で宣言する必要がありました(通常は@interface)。これで、コンパイラは、実装が.mファイルの前か後かを気にしません。

于 2012-08-14T23:01:02.503 に答える
2

コンパイラはその定義を見ることができます:

+ (double)popOperandOffProgramStack:(NSMutableArray *)stack
{
   double result = 0;
   return result;
}

したがって、宣言されていること、パラメータタイプ、およびリターンタイプを確認できます。

@implementationまた、古いコンパイラでは、使用前に使用する必要がありますが、スコープで使用する場合は使用できなくなります。

宣言されていなくても、objcは十分に弱いので、コンパイラエラーにはなりません(おそらく警告)。例外:ARCを使用している場合は、メソッドが表示されている必要があります。コンパイラは、ARCが有効になっている場合、参照カウントのセマンティクスとパラメータタイプを知る必要があります。

于 2012-08-14T23:01:11.513 に答える