菜鸟教程小白 发表于 2022-12-13 08:24:41

ios - 在 Objective-C 中使用 KVC 读取联合属性


                                            <p><p><strong>更新:</strong></p>

<p>我将问题归结为根本无法在下面看到的类上使用键值编码</p>

<pre><code>#import &lt;Foundation/Foundation.h&gt;
#import &lt;GLKit/GLKit.h&gt;

@interface CMTransformation : NSObject

@property(nonatomic) GLKVector3 position;
@property(nonatomic) GLKVector3 scale;
@property(nonatomic) GLKVector3 rotation;
@property(nonatomic) GLKVector3 anchor;

@property(nonatomic) GLKMatrix4 matrix;

- (GLKMatrix4)calculateMatrixWithParentTransformation:(CMTransformation *)parentTransformation;

@end
</code></pre>

<p>根据我的理解和经验,我应该能够将非 NSObject 作为 NSValue 提取出来,但是,我发现使用 KVC 语法无法访问这些项目(定义为联合):</p>

<pre><code>CMTransformation* trans = [ init];
temp = ;
</code></pre>

<p>同样,如果我尝试访问底层变量:</p>

<pre><code>CMTransformation* trans = [ init];
temp = ;
</code></pre>

<p>这两个都抛出异常,因为找不到 key 。我在这里错过了什么?</p>

<p><strong>上一个问题</strong></p>

<p>我编写了一些代码,允许我使用诸如“transformation.position”之类的字符串访问(有点)任意结构</p>

<p>由于某种原因,当我尝试从 NSObject 读取属性时,代码在第二次跳转时停止工作。这里是</p>

<pre><code>NSString* property = actionDetails[@&#34;Property&#34;];
PropertyParts = [ mutableCopy];
int count = ;
id current_object = initial_object;

for(int i = 0; i &lt; count; i++)
{
    NSString* current_part = PropertyParts;      
    current_object = ;
}
</code></pre>

<p>我已经尝试了所有可能的属性访问语法,包括 Property、property 和 _property。</p>

<p>这是自定义的 NSObject 声明</p>

<pre><code>#import &lt;Foundation/Foundation.h&gt;
#import &lt;GLKit/GLKit.h&gt;

@interface CMTransformation : NSObject

@property(nonatomic) GLKVector3 position;
@property(nonatomic) GLKVector3 scale;
@property(nonatomic) GLKVector3 rotation;
@property(nonatomic) GLKVector3 anchor;

@property(nonatomic) GLKMatrix4 matrix;

- (GLKMatrix4)calculateMatrixWithParentTransformation:(CMTransformation *)parentTransformation;

@end
</code></pre>

<p>另外,在第一个循环之后,我可以看到调试器说 CMTransformation* 正在填充 currrent_object,所以我不知道为什么我不能访问它的属性?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>您对实现 <em>valueForUndefinedKey:</em> 和 <em>setValue:forUndefinedKey:</em> 满意吗?</p>

<p>如果是这样,这可行:</p>

<pre><code>union Test
{
    CGFloat f ;
    NSInteger i ;
};

@interface TestClass : NSObject
@property ( nonatomic ) union Test t ;
@end

@implementation TestClass

-(void)setValue:(nullable id)value forUndefinedKey:(nonnull NSString *)key
{
    Ivar v = class_getInstanceVariable( [ self class ], [ [ NSString stringWithFormat:@&#34;_%@&#34;, key ] UTF8String ] ) ;
    if ( v )
    {
      char const * const encoding = ivar_getTypeEncoding( v ) ;
      if ( encoding == &#39;(&#39; ) // unions only
      {
            size_t size = 0 ;
            NSGetSizeAndAlignment( encoding, &amp;size, NULL ) ;

            uintptr_t ptr = (uintptr_t)self + ivar_getOffset( v ) ;
            [ (NSValue*)value getValue:(void*)ptr ] ;

            return ;
      }
    }

    objc_property_t prop = class_getProperty( [ self class ], [ key UTF8String ] ) ;
    if ( prop )
    {
      char const * const encoding = property_copyAttributeValue( prop, &#34;T&#34; ) ;
      if ( encoding == &#39;(&#39; )   // unions only
      {
            objc_setAssociatedObject( self, NSSelectorFromString( key ), value, OBJC_ASSOCIATION_COPY ) ;
            return ;
      }
    }

    [ super setValue:value forUndefinedKey:key ] ;
}

-(nullable id)valueForUndefinedKey:(nonnull NSString *)key
{
    Ivar v = class_getInstanceVariable( [ self class ], [ [ NSString stringWithFormat:@&#34;_%@&#34;, key ] UTF8String ] ) ;
    if ( v )
    {
      char const * const encoding = ivar_getTypeEncoding( v ) ;
      if ( encoding == &#39;(&#39; )
      {
            size_t size = 0 ;
            NSGetSizeAndAlignment( encoding, &amp;size, NULL ) ;

            uintptr_t ptr = (uintptr_t)self + ivar_getOffset( v ) ;
            NSValue * result = [ NSValue valueWithBytes:(void*)ptr objCType:encoding ] ;
            return result ;
      }
    }

    objc_property_t prop = class_getProperty( [ self class ], [ key UTF8String ] ) ;
    if ( prop )
    {
      return objc_getAssociatedObject( self, NSSelectorFromString( key ) ) ;
    }

    return [ super valueForUndefinedKey:key ] ;
}

@end


int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
      union Test u0 = { .i = 1234 } ;
      TestClass * const testClass = [ TestClass new ] ;

      [ testClass setValue:[ NSValue valueWithBytes:&amp;u0 objCType:@encode( typeof( u0 ) ) ] forKey:@&#34;t&#34; ] ;
      assert( testClass.t.i == 1234 ) ;

      NSValue * const result = [ testClass valueForKey:@&#34;t&#34; ] ;

      union Test u1 ;
      [ result getValue:&amp;u1 ] ;

      assert( u1.i == 1234 ) ;
    }
    return 0;
}
</code></pre>

<p>(粘贴到你的main.m文件中试试)</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在 Objective-C 中使用 KVC 读取联合属性,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/31006982/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/31006982/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在 Objective-C 中使用 KVC 读取联合属性