8

次のコードを検討してください。

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

typedef NSString* MyStringRef;
typedef NSString MyString;

@interface ClassA : NSObject
@property (nonatomic, copy) MyStringRef stringA;
@property (nonatomic, copy) MyString *stringB;
@end

@implementation ClassA
@synthesize stringA = _stringA;
@synthesize stringB = _stringB;
@end

int main() {
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList([ClassA class], &count);
    for (unsigned int i = 0; i < count; i++) {
        Ivar thisIvar = ivars[i];
        NSLog(@"thisIvar = %s, %s", ivar_getName(thisIvar), ivar_getTypeEncoding(thisIvar));
    }

    ClassA *a = [[ClassA alloc] init];
    NSLog(@"Out: %@", [a valueForKey:@"stringA"]);
    NSLog(@"Out: %@", [a valueForKey:@"stringB"]);
}

これは出力です:

$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix

$ clang -o typedef -fobjc-arc -framework Foundation typedef.m && ./typedef
2012-06-06 20:14:15.881 typedef[37282:707] thisIvar = _stringA, @"NSString"
2012-06-06 20:14:15.884 typedef[37282:707] thisIvar = _stringB, ^{NSString=#}
2012-06-06 20:14:15.885 typedef[37282:707] Out: (null)
2012-06-06 20:14:15.888 typedef[37282:707] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ClassA 0x7fabe0501480> valueForUndefinedKey:]: this class is not key value coding-compliant for the key stringB.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff835fef56 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff878e5d5e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff836891b9 -[NSException raise] + 9
    3   Foundation                          0x00007fff83e77703 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 240
    4   Foundation                          0x00007fff83dae38e _NSGetUsingKeyValueGetter + 108
    5   Foundation                          0x00007fff83dae315 -[NSObject(NSKeyValueCoding) valueForKey:] + 392
    6   typedef                             0x000000010e84bc6d main + 317
    7   typedef                             0x000000010e84b9c4 start + 52
)

ここで私が持っている質問は、Objective-Cについてtypedef NSString MyString、タイプの1つの変数を含む構造体を効果的に作成し、Classそれを使用する場所で使用するのはどういうことかということMyStringです。たとえば、構造体は次のようになります(これを参照した後):

struct NSString {
    Class a;
};

それはある意味理にかなっていますがvalueForKey:、おそらく現在は構造体であるために失敗します。そのため、オブジェクトと同じ方法でそれを返すことはできません。より正確には、ドキュメントで説明されている検索順序の「例外をスローする」部分に分類されます。

これが発生する原因となる言語と、2つのtypedefを同じように処理できない理由を理解したいと思います。

4

2 に答える 2

3

私はWWDC2012でこれに対する答えを得ました。この動作は、GCCとのバイナリ互換性の場合と同様に予想されることがわかりました。

バグが古いGCCとバイナリ互換であると私が考えるものを効果的に導入するのは奇妙に思えます。この種のものが最終的に段階的に廃止され、正しいコンパイラーが採用されることを願っています。

于 2012-07-21T19:07:37.377 に答える
1

これを再現できますが、gccでのみ再現できます。clangを使用すると、次のようになります。

$ clang --version
Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
Target: x86_64-apple-darwin10
Thread model: posix
$ ./a.out
2012-06-06 15:16:37.947 a.out[61063:903] thisIvar = _stringA, @"NSString"
2012-06-06 15:16:37.949 a.out[61063:903] thisIvar = _stringB, @"NSString"
2012-06-06 15:16:37.949 a.out[61063:903] Out: (null)
2012-06-06 15:16:37.950 a.out[61063:903] Out: (null)

したがって、clang開発者はそれがどのように機能するかについてあなたに同意しているようです。

(Apple clangバージョン3.0も試しました。同じ良い結果です。)

于 2012-06-06T20:21:35.560 に答える