Доступ к акселерометру iPhone с помощью PyObjC

Я хочу получить доступ к акселерометру моего iPhone через PyObjC. Вот мой код:

@objc.signature("v@:@@")
def accelerometer_didAccelerate_(self, accelerometer, acceleration):
    msgBox = UIAlertView.alloc().initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles_("Acceleration", str(acceleration.x), self, "OK", None)
    msgBox.show()
    msgBox.release()

@objc.signature("v@:@")
def applicationDidFinishLaunching_(self, unused):
    self.accelerometer = UIAccelerometer.sharedAccelerometer()
    self.accelerometer.setUpdateInterval_(1)
    self.accelerometer.setDelegate_(self)
    #...

Проблема в том, что str(accelleration.x) возвращает "<native-selector x of <UIAcceleration: 0x.....>>", Что я могу сделать?

1 ответ

UIAcceleration"s x-значение определяется в Objective-C как свойство и доступ к acceleration.x в Python дает вам метод с именем 'x', а не атрибут (ivar) с именем 'x', как вы могли ожидать. Вы должны сказать:

acceleration._.x

который использует "волшебный" механизм доступа PyObjC, чтобы получить нужный атрибут.

Причины этого:

Как работают пространства имен классов Python, вы не можете иметь метод и атрибут с одинаковым именем. Это отличается от Objective-C, где метод получения часто имеет то же имя, что и атрибут, к которому он обращается.

Это различие может вызвать небольшую путаницу с возможностью свойств Objective-C 2.0, тем более что синтаксис выглядит одинаково для двух языков. В Objective-C вы пишете:

NSLog(@"foo's bar: %f", foo.bar);
foo.bar = 10.0;

Который автоматически использует правильные методы установки или получения (-bar а также -setBar:). PyObjC, из-за правила пространства имен класса Python, не может делать в точности то, что должен делать код Objective-C, и ему нужно выбрать только одну вещь (метод или атрибут), которая будет представлена ​​именем foo.bar; вещь, которую он выбирает, это метод.

Другие вопросы по тегам