gpt4 book ai didi

objective-c - 按名称调用 Property setter 的最佳方式是什么?

转载 作者:搜寻专家 更新时间:2023-10-30 19:43:00 25 4
gpt4 key购买 nike

我正在构建一个可以连接到一系列底层对象属性的通用 UI,因此我想按名称调用 getter 和 setter。我尝试过使用 NSInvocation,也看到其他人使用 setValue:forKey。但我想用最快的方法。

如果我持有对 NSInvocation 实例的引用,我可以非常快速地调用 invoke,但我有一个问题 - 如何使用它调用属性 setter ?像这样在 setter/getter 上效果很好:

SEL propSelector = NSSelectorFromString(propertyName);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[target class]instanceMethodSignatureForSelector:propSelector]];
[inv setSelector:propSelector];
[inv setTarget:target];
[inv invoke];
float value;
[inv getReturnValue:&value];

但我一直没能找到一种方法来为选择器赋值。使用 setArgument:atIndex: 似乎不起作用。

因此,我转而使用 setValue:forKey: 方法,但我担心随着时间的推移性能会迅速下降。

有什么想法吗?

最佳答案

我不完全理解您要实现的目标,但我已经快速测试了 valueForKey: 与您的调用方法的性能。在我的测试中,下面的代码 valueForKey: 几乎比 NSInvocation 方法快 5 倍。

  1. 1.620685 毫秒
  2. 30.357355 毫秒
  3. 7.593611 毫秒

代码:

#import <Foundation/Foundation.h>
#include <mach/mach_time.h>


@interface Foo : NSObject
{
NSNumber *value;
}

@property (nonatomic, retain) NSNumber *value;

@end

@implementation Foo

@synthesize value;

- (void) dealloc
{
[value release];
[super dealloc];
}

@end

#pragma mark MAIN
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// prepare loops
NSUInteger i;
NSUInteger max = 10000;
Foo *target = [[[Foo alloc] init] autorelease];
target.value = [NSNumber numberWithFloat:12.345f];
NSString *valueKey = @"value";

// prepare mach timebase
mach_timebase_info_data_t timebase;
mach_timebase_info(&timebase);
double ticksToNanoseconds = (double)timebase.numer / timebase.denom;

// old-fashioned
uint64_t startTime = mach_absolute_time();
for (i = 0; i < max; i++) {
NSNumber *numValue = [target valueForKey:valueKey];
}
uint64_t elapsedTime = mach_absolute_time() - startTime;
double elapsedTimeInNanoseconds = elapsedTime * ticksToNanoseconds;
NSLog(@"1: %f millisec", elapsedTimeInNanoseconds / 1000000);

// invocation
startTime = mach_absolute_time();
for (i = 0; i < max; i++) {
SEL propSelector = NSSelectorFromString(valueKey);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[target class] instanceMethodSignatureForSelector:propSelector]];
[inv setSelector:propSelector];
[inv setTarget:target];
[inv invoke];
NSNumber *numValue;
[inv getReturnValue:&numValue];
}
elapsedTime = mach_absolute_time() - startTime;
elapsedTimeInNanoseconds = elapsedTime * ticksToNanoseconds;
NSLog(@"2: %f millisec", elapsedTimeInNanoseconds / 1000000);

// reused invocation
SEL propSelector = NSSelectorFromString(valueKey);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[target class] instanceMethodSignatureForSelector:propSelector]];

startTime = mach_absolute_time();
for (i = 0; i < max; i++) {
[inv setSelector:propSelector];
[inv setTarget:target];
[inv invoke];
NSNumber *numValue;
[inv getReturnValue:&numValue];
}
elapsedTime = mach_absolute_time() - startTime;
elapsedTimeInNanoseconds = elapsedTime * ticksToNanoseconds;
NSLog(@"3: %f millisec", elapsedTimeInNanoseconds / 1000000);

// clean and return
[pool drain];
return 0;
}

关于objective-c - 按名称调用 Property setter 的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4549815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com