私はObjective Cが初めてで、オブジェクトを使って練習しています。のようなものはFraction* f = [[Fraction alloc] init ];
機能しますが、やろうとするたびにFraction c;
Is Interface type cannot be statically allocated
there とにかく、スタックにオブジェクトを割り当てる (C++ のように) ? というメッセージが表示されます。または私は間違ったことをしようとしていますか?
6 に答える
Objective C ではオブジェクトを静的に割り当てることはできません。これには多くの理由があります。オブジェクトを初期化する必要がありますが、初期化メソッドはオブジェクトのアドレスを変更できるという事実を含みます。
C++ では、コンストラクターは呼び出されたオブジェクトを初期化する必要があり、オブジェクト アドレスを変更することはできません。これは、Objective C には当てはまりません。コンストラクター (alloc+init* シーケンスまたはクラス レベル メソッド) に相当するものは、呼び出されたオブジェクトのアドレスを変更するかどうかを決定できます (もちろん、元のオブジェクトを解放します)。
もちろん、静的に割り当てられたメモリを解放したり、スタックのアドレスを変更したりする方法はありません。
技術的には可能ですが (以下のコードを参照)、すべきではありません。また、スタックであろうとヒープであろうと、オブジェクト自体ではなく、オブジェクトへのポインタしかありません。つまりFraction *c
、 ではなくと書くべきFraction c
です。
// Allocate an Objective-C object on the stack.
// Original code By Graham Lee:
// https://gist.github.com/iamleeg/5290797
#import <Foundation/Foundation.h>
#include <stdlib.h>
#include <objc/runtime.h>
@interface A : NSObject
@property (assign) int meaning;
@end
@implementation A
- (id)init {
if ([super init]) {
_meaning = 42;
}
return self;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
// allocate and zero stack memory
size_t size = class_getInstanceSize([A class]);
id obj = (__bridge_transfer id) alloca(size);
memset((__bridge void*)obj, 0, size);
// set class and initialize the object
object_setClass(obj, [A class]);
obj = [obj init];
NSLog(@"meaning: %d", [obj meaning]);
// transfer ownership from ARC to CF so ARC doesn't
// try to improperly free the stack allocated memory
CFTypeRef ref = (__bridge_retained CFTypeRef) obj;
}
}
alloca()
非標準で、安全でなく、移植性がなく、スタック オーバーフローが発生しやすいです。
いいえ、すべてのオブジェクトは Obj-C のヒープに割り当てられます。
いいえ、Objective-C オブジェクトのメモリにスタックを使用することはできません。スタックはヒープでなければなりません ( および を介しalloc
てinit
)。
@ wattson12 が指摘したように、明らかにオブジェクト参照 (ポインター) をスタックに格納できますが、これはオブジェクトのメモリにスタックを使用しません。
発生しているエラーは構文エラーが原因です。次のことを行う必要があります。
Fraction *c;
これがオブジェクトへのポインターであることを示す * がないことに注意してください (このオブジェクトをスタックに格納しているのではなく、(潜在的な) オブジェクトへの参照を作成しているだけです)