问题描述
我正在使用 UISpec 在我的项目中进行自动化测试.一切都很好,直到 Apple 发布带有 iOS 6 SDK 的 xCode 4.5.现在无法编译 UISpec 项目,因为 UITouch 类类别中的错误列表.代码如下:
I'm using UISpec for automated testing in my project. Everything was fine until Apple released xCode 4.5 with iOS 6 SDK. Now UISpec project can't be compiled because a list of errors in category of UITouch class. Here is the code:
//
// TouchSynthesis.m
// SelfTesting
//
// Created by Matt Gallagher on 23/11/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
@implementation UITouch (Synthesize)
//
// initInView:phase:
//
// Creats a UITouch, centered on the specified view, in the view's window.
// Sets the phase as specified.
//
- (id)initInView:(UIView *)view
{
self = [super init];
if (self != nil)
{
CGRect frameInWindow;
if ([view isKindOfClass:[UIWindow class]])
{
frameInWindow = view.frame;
}
else
{
frameInWindow =
[view.window convertRect:view.frame fromView:view.superview];
}
_tapCount = 1;
_locationInWindow =
CGPointMake(
frameInWindow.origin.x + 0.5 * frameInWindow.size.width,
frameInWindow.origin.y + 0.5 * frameInWindow.size.height);
_previousLocationInWindow = _locationInWindow;
UIView *target = [view.window hitTest:_locationInWindow withEvent:nil];
_window = [view.window retain];
_view = [target retain];
_phase = UITouchPhaseBegan;
_touchFlags._firstTouchForView = 1;
_touchFlags._isTap = 1;
_timestamp = [NSDate timeIntervalSinceReferenceDate];
}
return self;
}
//
// setPhase:
//
// Setter to allow access to the _phase member.
//
- (void)setPhase:(UITouchPhase)phase
{
_phase = phase;
_timestamp = [NSDate timeIntervalSinceReferenceDate];
}
//
// setPhase:
//
// Setter to allow access to the _locationInWindow member.
//
- (void)setLocationInWindow:(CGPoint)location
{
_previousLocationInWindow = _locationInWindow;
_locationInWindow = location;
_timestamp = [NSDate timeIntervalSinceReferenceDate];
}
@end
编译器在诸如_tapCount = 1;"之类的行上给出错误错误是未知类型名称_tapCount";你的意思是...?
compiler gives errors on lines like "_tapCount = 1;" error is "Uknown type name "_tapCount"; did you mean ...?"
我做了什么:
- 获取 UITouch 类的实例变量列表,使用运行时函数class_copyIvarList"并检查这些变量是否仍然存在.
尝试在运行时更改所需的值,例如
- get a list of instance variable for UITouch class, using run time function "class_copyIvarList" and checked if these variables still exist. they do.
tried to change needed values at runtime, like
uint uPhase = UITouchPhaseBegin;object_setInstanceVariable(self, "_phase", &uPhase);
uint uPhase = UITouchPhaseBegin;object_setInstanceVariable(self, "_phase", &uPhase);
或
Ivar var = class_getInstanceVariable([self class], "_phase");
object_setIvar(self, var, [NSNumber numberWithInt:UITouchPhaseBegin]);
在这两种情况下,都将无效值写入_phase"成员.我通过将 UITouch 实例的描述打印到控制台来检查这一点.它被写成阶段:未知".
in both cases invalid value was written to "_phase" member. i checked that by printing description of the UITouch instance to console. it was written "phase: Uknown".
然后我决定尝试键值编码并实现它:
then i decided to try key-value coding and implemented it like:
[self setValue:[NSNumber numberWithInt:1] forKey:@"tapCount"];
[self setValue:[NSNumber numberWithInt:UITouchPhaseBegin] forKey:@"phase"];
现在它给出了一些结果.编译错误被消除,UITouch 实例的成员值被更改,但仍然没有任何反应.我在适当的 UI 对象(在我的例子中是 UIButton)的touchesBegan:..."和touchesEnded:..."方法中设置断点并调试它.这些方法被调用,但没有任何反应 - 按钮处理程序没有被调用.
now it gave some results. compile errors are eliminated, member values of UITouch instance are changed but still nothing happens. i set breakpoints in "touchesBegan:..." and "touchesEnded:..." methods of appropriate UI object (it was UIButton in my case) and debugged it. these methods are called, but nothing happens - button handler is not called.
同样由于 KVC,我不得不注释 UITouch 类别的方法setPhase"和setLocationInWindow",否则会发生无限递归.属性的 setter 调用自身.
also due to KVC i had to comment methods "setPhase" and "setLocationInWindow" of UITouch category, otherwise endless recursion happens. setter of the property calls itself.
现在我没有想法了.这个类别是由 Matt Gallagher 于 23/11/08 创建.",这意味着它是 UISpec 的第三方代码.所以我希望它在除 UISpec 之外的其他地方使用,并且有人知道解决方法.
now i'm out of ideas. this category is "Created by Matt Gallagher on 23/11/08.", that means it is a third party code for UISpec. so i hope it is used somewhere else except the UISpec and somebody knows a work around.
谢谢.
附言我知道这是一个私有 API.它不包含在项目的发布配置中.我只需要它用于自动化测试
P.S. i know that this is a private API. it is not included to the release configuration of the project. i need it only for automated testing
推荐答案
您无需更改 UIQuery.m 文件中的任何内容.请将以下代码行添加到 UIQuery.h 文件中:
You do not have to change anything in UIQuery.m file. Please add following lines of code to UIQuery.h file :
#ifdef __IPHONE_6_0
@interface UITouch () {
NSTimeInterval _timestamp;
UITouchPhase _phase;
UITouchPhase _savedPhase;
NSUInteger _tapCount;
UIWindow *_window;
UIView *_view;
UIView *_gestureView;
UIView *_warpedIntoView;
NSMutableArray *_gestureRecognizers;
NSMutableArray *_forwardingRecord;
CGPoint _locationInWindow;
CGPoint _previousLocationInWindow;
UInt8 _pathIndex;
UInt8 _pathIdentity;
float _pathMajorRadius;
struct {
unsigned int _firstTouchForView:1;
unsigned int _isTap:1;
unsigned int _isDelayed:1;
unsigned int _sentTouchesEnded:1;
unsigned int _abandonForwardingRecord:1;
} _touchFlags;
}
@end
#endif
谢谢.
这篇关于以编程方式在 xCode 4.5 中模拟 UITouch (UISpec)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!