【问题标题】:Is it possible to create a CLHeading object in Objective C?是否可以在 Objective C 中创建 CLHeading 对象?
【发布时间】:2011-01-15 03:19:37
【问题描述】:

我正在尝试实现一个插入式位置管理器子类,以允许我将航向数据传递给 iphone 模拟器,类似于 unimotion/accelerometer hack。不幸的是,根据CLHeading docs,所有内容都是只读的,并且没有允许设置标题的初始化程序。有没有办法强制创建一个填充的 CLHeading 实例?

【问题讨论】:

    标签: iphone objective-c iphone-sdk-3.0


    【解决方案1】:

    另一种方法是继承 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 的值,您可以声明自己的存储属性并将其命名为不同于被覆盖属性的名称。

    【讨论】:

    • 你不能用存储的属性覆盖!
    • @WilliamGrand 我更新了我的答案以说明这是怎么可能的。如果需要,很高兴进一步澄清。希望对您有所帮助。
    【解决方案2】:

    如果您可以使用私有方法(私有或企业应用程序),您可以将CLHeading+Init.h添加到您的项目中:

    @interface CLHeading (Init)
    
    - (id)initWithHeading:(double)heading accuracy:(double)accuracy;
    
    @end
    

    我在我的位置模拟器中使用它https://github.com/maciekish/MockingPlace

    警告!这将使您的应用被 App Store 拒绝!

    【讨论】:

      【解决方案3】:

      由于 Objective-C 是一种动态类型语言,您可以创建自己的类(例如,MyFakeHeading),只要它响应 CLHeading 所做的所有相同选择器,您就可以简单地转换它作为CLHeading 并将其作为参数传递。而且,由于您只需要伪造自己的代码,您甚至不需要实现CLHeading 的所有功能,只需实现您正在使用的部分即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-06
        • 2010-10-13
        相关资源
        最近更新 更多