0

私が書き込もうとすると

NSLog(@"%d", myObject.myId);

myIdがintの場合、コンソールは70614496のような高い数値を示します。また、を使用する@"%@"と、例外が発生します-[CFNumber respondsToSelector:]: message sent to deallocated instance 0x466c910。なんでそうなの?

myObjectの定義は次のとおりです。

@interface myObject : NSObject {
int myId;
NSString *title;
}

@property(nonatomic) int myId;
@property(nonatomic, retain) NSString *title;

@end

@implementation myObject

@synthesize myId, title;

- (void)dealloc {
[title release];

[super dealloc];
}

@end
4

6 に答える 6

4

クラス/オブジェクト/インスタンス変数がすべて正しく設定されている場合、最初に試した方法で動作するはずであることを示す例を次に示します。

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
{
  int myId;
}

@property int myId;
@end

@implementation MyClass
@synthesize myId;
@end

int main (int argc, const char * argv[]) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  MyClass *myObject = [[MyClass alloc] init];

  myObject.myId = 5;
  NSLog(@"%d", myObject.myId);

  [myObject release];
  [pool drain];
  return 0;
}

あなたのコードは、次の行と同等のことを示しています。

NSLog(@"%d", MyClass.myId);

これはコンパイルさえせず、エラーが発生します:

foundation.m:21: error: accessing unknown 'myId' class method
于 2009-11-10T19:46:55.583 に答える
4

カールは、あなたのコードをコンパイルできるようにうまくやってくれています。あなたの質問は混乱を暗示しているように見えるので、 %@ 形式指定子に関する別の単語です。

NSLog 形式で %@ を使用すると、実際には引数に説明メッセージが送信され、結果の文字列が出力されます。が int であり、NSObject のインスタンスではない場合myId、説明メッセージに応答しません。int 値には %d を使用し、NSNumber インスタンスには %@ を使用します。

于 2009-11-10T19:50:37.043 に答える
1

2番目のエラーメッセージを考えると、は正常に機能していると思いますが、整数を割り当てる必要があるとき%dに、CFNumberまたはNSNumberをプロパティに割り当てているところがあります。myID

于 2009-11-10T23:06:55.193 に答える
0

myObject のインスタンスは、ある時点で自動解放され、実際には有効ではなくなったようです。そのため、オブジェクトとして逆参照しようとすると、奇妙な NSNumber の問題が発生します。整数を要求するだけでは、エラーは発生しません。整数に強制されたポインターのアドレスが表示されるだけです。

myObject の割り当てがいつ解除されるかを確認するにdeallocは、クラスのメソッドに次のようなものを追加してみてください。

- (void)dealloc
{
    NSLog(@"dealloc called on %@", self);
    [title release];
    [super dealloc];
}

myObject.myID のログが表示される前に、このログが dealloc であることがわかると思います。

于 2009-11-11T04:56:32.603 に答える
-1

これを単純に変更してみます:

@property(nonatomic) int myId;

これに:

@property(nonatomic, assign) int myId;

そして、あなたの結果を教えてください。古いintを新しいintに割り当てるときに、obj-cが何かおかしなことをしていると思いますか?

于 2009-11-11T17:35:11.523 に答える
-1

NSLog ステートメントをフォーマットする方法については、String Format Specifiersを参照してください。オブジェクトには、書式設定された文字列を返す組み込みの -description メソッドがあるため、NSLog を使用するのは簡単です。スケーラー値については、適切なフォーマッターを使用する必要があります。

ハードウェアからハードウェアに移行すると精度が変化するため、オブジェクト変換を使用して値をログに記録する習慣を身につけることをお勧めします。この場合:

NSLog(@"%@", [[NSNumber numberFromInt:myObject.myId] stringValue]);

これは常に正しく印刷されます。


編集#1:申し訳ありません。上記を書いていたら寝不足でした。私が実際に意図したのは、単純な vs の使用と with での印刷intに対して警告することでした。NSIntegerNSNumber numberWithInteger:

64 ビット ハードウェアでの次の実行を検討してください。

int x=pow(2,63);
NSLog(@"x=%d",x); //prints x=2147483647

NSInteger n=pow(2,63);
NSLog(@"n=%d",n); // prints n=-1
NSLog(@"n=%@",[[NSNumber numberWithInteger:n] stringValue]); // prints n=9223372036854775807

8 ビット システムの昔は、常に 8 ビットの 'int' を使用すると問題が発生しました。256 回を超える反復で for ループを実行するには、long. 32 ビットでは、この種の問題は見られず、変数intのサイズを追跡する習慣が身に付くこともありません。int

これは、データ内の非常に具体的でまれな値でのみ発生するため、追跡がほぼ不可能な悪質なバグにつながる可能性があります。

iPhone (またはその他の将来のモバイル/プラットフォーム) 向けに作成するということは、昔と同じように、非常に可変性の高いハードウェアで作成することを意味します。システムおよび API 固有の定義を使用する習慣を早い段階で身に付けることが最善です。


編集#2:

ここで myId は int で、コンソールは 70614496 のような高い数字を返します。

(1) 実行するたびに異なる数値が出力される場合は、おそらく、設定時に int にポインターを割り当てています。NSLog は、ポインターの値を int として正しく出力しています。

(2) 毎回同じ数字を出力する場合、上記の最初の編集のようにオーバーフローの問題が発生している可能性があります。

いずれの場合も、idプロパティに値を代入するコードを確認する必要があります。出力する場所ではありません。

于 2009-11-10T20:32:11.437 に答える