【发布时间】:2011-01-15 03:19:37
【问题描述】:
我正在尝试实现一个插入式位置管理器子类,以允许我将航向数据传递给 iphone 模拟器,类似于 unimotion/accelerometer hack。不幸的是,根据CLHeading docs,所有内容都是只读的,并且没有允许设置标题的初始化程序。有没有办法强制创建一个填充的 CLHeading 实例?
【问题讨论】:
标签: iphone objective-c iphone-sdk-3.0
我正在尝试实现一个插入式位置管理器子类,以允许我将航向数据传递给 iphone 模拟器,类似于 unimotion/accelerometer hack。不幸的是,根据CLHeading docs,所有内容都是只读的,并且没有允许设置标题的初始化程序。有没有办法强制创建一个填充的 CLHeading 实例?
【问题讨论】:
标签: iphone objective-c iphone-sdk-3.0
另一种方法是继承 CLHeading 并覆盖您关心的属性 getter 和 setter。
以下是 Swift 中的示例:
main.swift:
import CoreLocation
class SubclassOfCLHeading: CLHeading {
open override var magneticHeading: CLLocationDirection {
get {
print("getter invoked")
return 12345
}
set {
print("setter invoked \(newValue)")
}
}
}
let heading = SubclassOfCLHeading()
print(heading.magneticHeading)
heading.magneticHeading = 54321
运行这个会产生...
getter invoked
12345.0
setter invoked 54321.0
在 Objective-C 中也是这样:
main.m:
#import <Foundation/Foundation.h>
#import "SubclassOfCLHeading.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
SubclassOfCLHeading *heading = [[SubclassOfCLHeading alloc] init];
NSLog(@"%f", heading.magneticHeading);
heading.magneticHeading = 54321;
}
return 0;
}
SubclassOfCLHeading.h:
#import <CoreLocation/CoreLocation.h>
@interface SubclassOfCLHeading : CLHeading
@property(nonatomic) CLLocationDirection magneticHeading;
@end
SubclassOfCLHeading.m:
#import "SubclassOfCLHeading.h"
@implementation SubclassOfCLHeading
- (CLLocationDirection)magneticHeading {
NSLog(@"getter invoked");
return 12345;
}
- (void)setMagneticHeading:(CLLocationDirection)magneticHeading {
NSLog(@"setter invoked %f", magneticHeading);
}
@end
在任一示例中,如果您想存储传递给 setter 的值,您可以声明自己的存储属性并将其命名为不同于被覆盖属性的名称。
【讨论】:
如果您可以使用私有方法(私有或企业应用程序),您可以将CLHeading+Init.h添加到您的项目中:
@interface CLHeading (Init)
- (id)initWithHeading:(double)heading accuracy:(double)accuracy;
@end
我在我的位置模拟器中使用它https://github.com/maciekish/MockingPlace
警告!这将使您的应用被 App Store 拒绝!
【讨论】:
由于 Objective-C 是一种动态类型语言,您可以创建自己的类(例如,MyFakeHeading),只要它响应 CLHeading 所做的所有相同选择器,您就可以简单地转换它作为CLHeading 并将其作为参数传递。而且,由于您只需要伪造自己的代码,您甚至不需要实现CLHeading 的所有功能,只需实现您正在使用的部分即可。
【讨论】: