我正在使用动画师来实现动画,比如
[[self.view animator] setFrame:newFrame];
Run Code Online (Sandbox Code Playgroud)
但是我希望在动画完成后运行一个方法或块,如下所示:
[[self.view animator] setFrame:newFrame onComplete:^{
NSLog(@"****");
}];
Run Code Online (Sandbox Code Playgroud)
有没有办法实现它?
如何在代码上从下到上移动视图:
colorView.hidden=NO;
colorView=[[UIView alloc]init];
colorView.frame=CGRectMake(0,480,320, 480);
colorView.bounds=CGRectMake(0,200,320, 280);
colorView.backgroundColor=[UIColor greenColor];
colorView.alpha=1.0f;
[webView addSubview:colorView];
[self.view addSubview:webView];
[self createTransparentView];
Run Code Online (Sandbox Code Playgroud)
那我怎么能在这里添加动画呢?
我正在尝试将淡入淡出应用于我在另一个上面以编程方式创建的UIView.
[UIView animateWithDuration:0.5 animations:^(void) {
[self.view setAlpha:0];
}
completion:^(BOOL finished){
[self.view removeFromSuperview];
}];
Run Code Online (Sandbox Code Playgroud)
完成的事件在0.5秒之后被正确调用,但我没有看到任何淡入淡出(我应该看到底部的UIView).
如果不使用alpha,我会移开UIView它可以工作(我看到底部UIView,而顶部UIView滑落),所以它似乎是一个与alpha相关的问题,但我无法弄清楚什么是错的!
[UIView animateWithDuration:0.5 animations:^(void) {
CGRect o = self.view.frame;
o.origin.x = 320;
self.view.frame = o;
}
completion:^(BOOL finished){
[self.view removeFromSuperview];
}];
Run Code Online (Sandbox Code Playgroud)
我之前使用过alpha动画,它们通常以这种方式工作......
背景
我正在寻找一种方法来实现类似于Frank库用于实现"本机iOS应用程序的自动验收测试"的方案,但我希望这种方案依赖于原生的iOS/MacOSX技术.对不起,TLDR但它值得详细解释.
1.这里是弗兰克是如何工作的一个简短的概述:
它有客户端和服务器部件.
服务器部分嵌入到我们要运行验收测试的应用程序中.Frank教程向我们展示了如何创建应用程序主目标的重复目标,并将Frank HTTP服务器嵌入其中.
客户端部分 - 主要是运行纯文本场景的Cucumber:每个场景包含应针对应用程序运行的指令(填充文本字段,触摸按钮,确保页面上存在特定元素等...).此外,每个场景都会启动自己的app实例,这意味着每次进入新场景时都会提供一个新的状态.
客户端(Cucumber和Ruby-to-Objective-C桥接器)通过HTTP协议与服务器(嵌入到应用程序中的HTTP服务器)进行通信.它使用特殊约定,因此客户端可以告诉服务器应用程序应该执行的操作,以便可以执行特定方案.
2.最近,我发现弗兰克·皮特霍奇森的作者所写的以下文章:
http://blog.thepete.net/blog/2012/11/18/writing-ios-acceptance-tests-using-kiwi/
他建议更简单的方法为不喜欢依赖Cucumber和Ruby等外部工具的开发人员编写验收测试.让我自己引用作者:
在我开始之前,让我明确一点,我个人不会使用这种方法来编写验收测试.我更喜欢使用像ruby这样的高级语言来编写这些类型的测试.假设你对红宝石感到满意,那么测试代码的工作量就会减少,表达方式也会更具表现力.这就是我想尝试这个实验的原因.随着时间的推移,我和很多iOS开发人员谈过,他们不喜欢用红宝石编写测试.他们在Objective-C中比其他任何东西都更舒服,并且希望用他们用于生产代码的相同语言编写测试.很公平.
这篇博客文章激励我快速推出自己非常原始和原始的工具,这正是Pete在他的博客文章中所描述的:NativeAutomation.
实际上,就像Pete所描述的那样,可以通过使用放置在简单OCTests目标中的Kiwi/PublicAutomation设置来运行验收测试.我真的很喜欢它,因为:
tapButtonWithTitle,fillTextFieldWithPlaceholder,hasLabelWithTitle等等......
它不需要外部工具和语言:不需要使用Cucumber/Ruby或其他任何东西.NativeAutomation本身只使用Frank也使用的PublicAutomation.需要PublicAutomation来模拟应用程序屏幕上的用户交互:触摸,填充,手势......
通过运行Cocoa Unit Tests包从Xcode运行这些测试非常方便.(虽然命令行构建也很容易).
问题
问题的Kiwi/PublicAutomation方法是将整个测试套件嵌入到应用程序包中.这意味着在每个场景运行后,在下一个场景开始执行之前,无法重置应用程序以强制它处于新鲜状态.解决此问题的唯一方法是Kiwi's beforeEach使用执行应用程序的软重置的方法编写钩子,如:
+ (void)resetApplication {
[Session invalidateSession];
[LocationManager resetInstance];
[((NavigationController *)[UIApplication sharedApplication].delegate.window.rootViewController) popToRootViewControllerAnimated:NO];
[OHHTTPStubs removeAllStubs];
cleanDatabase();
shouldEventuallyBeTrue(^BOOL{
return FirstScreen.isCurrentScreen;
});
Run Code Online (Sandbox Code Playgroud)
但是在涉及网络,异步作业,核心数据,文件操作的应用程序的情况下,很难对先前场景留下的东西进行真正的拆解.
题
上面描述的问题使我思考是否有可能实现类似于Frank方法的更复杂的方法,第二个应用程序与主应用程序的捆绑包不同,并且不依赖于像Cucumber(Ruby)这样的外部工具.
以下是我如何看待它的完成方式.
除了主应用程序(MainApp)之外,还有第二个iOS(或Mac OS X)应用程序(AcceptanceTestsRunnerApp),它包含整个验收测试套件,并针对主应用程序包运行此套件:
它会在进入每个新场景之前启动新的模拟器实例,并针对当前模拟器的应用程序实例执行当前场景.
问题是:
我不太了解允许我这样做的Mac OSX或iOS技术:我不知道是否甚至可以设置可以控制主应用程序的Mac OS X/iOS应用程序(AcceptanceTestsRunnerApp) (MainApp)并针对它运行验收测试场景.
对于那些对使用原生Objective-C工具编写iOS应用程序验收测试的人感觉更舒服的人,我会感激不尽.
更新后来
...我确实阅读了一些关于XPC服务的文档,但具有讽刺意味的是,我正在寻找的方案应该与XPC文档建议的方案完全相反: …
Function *fun = call->getCalledFunction();
Run Code Online (Sandbox Code Playgroud)
getCalledFunction();如果是间接调用则返回 null。如何获取函数的名称或指针的名称?
我发现Stack Overflow中与此问题相关的所有问题都谈到了直接调用的函数名称或指针类型。
我只想跟踪这样的案例:
void foo(){}
void goo(){}
void main(){
int x = 1;
void (*p)();
if(x)
p = &foo;
else
p = &goo;
p(); // print the called function name
}
Run Code Online (Sandbox Code Playgroud) 我们正在围绕LLVM库进行研究,我们发现IR库有时会达到最多29个方法调用的调用堆栈.
有时当我在iOS框架中看到一些崩溃时,我也会观察到相当深的调用堆栈.
我的问题是,我们是否可以推断一个代码的设计是否存在问题,而这个代码的设计自称是如此之大.
这是一个例子:
/usr/local/LLVM/llvm/unittests/IR/AttributesTest.cpp:54
/usr/local/LLVM/llvm/lib/IR/LLVMContext.cpp:162
/usr/local/LLVM/llvm/lib/IR/LLVMContext.cpp:162
/usr/local/LLVM/llvm/lib/IR/LLVMContextImpl.cpp:54
/usr/local/LLVM/llvm/lib/IR/LLVMContextImpl.cpp:59
/usr/local/LLVM/llvm/lib/IR/Module.cpp:60
/usr/local/LLVM/llvm/lib/IR/Module.cpp:62
/usr/local/LLVM/llvm/lib/IR/Module.cpp:456
/usr/local/LLVM/llvm/lib/IR/Function.cpp:350
/usr/local/LLVM/llvm/lib/IR/BasicBlock.cpp:98
/usr/local/LLVM/llvm/include/llvm/ADT/ilist.h:282
/usr/local/LLVM/llvm/include/llvm/ADT/ilist.h:267
/usr/local/LLVM/llvm/lib/IR/SymbolTableListTraitsImpl.h:76
/usr/local/LLVM/llvm/lib/IR/BasicBlock.cpp:90
/usr/local/LLVM/llvm/lib/IR/SymbolTableListTraitsImpl.h:58
/usr/local/LLVM/llvm/lib/IR/ValueSymbolTable.cpp:75
/usr/local/LLVM/llvm/lib/IR/ValueSymbolTable.cpp:47
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:112
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:96
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:777
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:75
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:771
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:132
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:122
/usr/local/LLVM/llvm/include/llvm/Support/Casting.h:75
/usr/local/LLVM/llvm/include/llvm/IR/Value.h:759
Run Code Online (Sandbox Code Playgroud)
PS示例调用堆栈实际上是由LLVMContext类的析构函数生成的:LLVMContext::~LLVMContext().这是来自Java世界的一篇非常古老的帖子的另一个例子:Java调用栈 - 从HTTP到JDBC作为图片.
我希望看到更详细的输出clang,比运行时产生的更多clang -v.
到目前为止,我尝试:clang --help,clang --help-hidden和clang -cc1 --help,但没有发现任何东西,这将有助于.
我特别感兴趣的是我是否可以看到一个推理的痕迹,clang它决定是否必须重新编译特定的.cpp文件.
我没有使用Xcode测试版.当我尝试做一个Build或者Run代码时,通常需要1-2分钟的时间.当我在5-6左右工作时,我的系统卡住了更多.当我检查活动监测大量内存采取的是SourceKitService和lldb-rpc-server,这需要大约6 GB.终止这些服务系统后工作正常.我在一周左右就遇到了这个问题,并且在Swift 3中写了特定单个项目的问题.
知道问题可能是什么?
我有一个UINavigationController嵌套的实例UITabBarController.我使用导航控制器到达某个视图控制器(标签栏仍然可见),从中我切换到第二个视图控制器(标签栏不再可见).
在第二个视图控制器中,只要我调用:
[self.navigationController setToolbarHidden:NO]
应用程序冻结并且内存增长,直到OOM异常崩溃.
我承认不建议将导航控制器嵌套在标签栏中,但是这个设置似乎在iOS 11之前正常工作.
编辑:当停止执行时,我看到很多调用:
UIView(UIConstraintBasedLayout)
UIView(AdditionalLayerSupport)
NSLayoutConstraint
这是完整的堆栈跟踪
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP * frame #0: 0x0000000106dd895c libobjc.A.dylib`objc_msgSend
+ 28
frame #1: 0x00000001067b6b9b Foundation`-[NSConcreteMapTable removeObjectForKey:] + 138
frame #2: 0x00000001069e6019 Foundation`_substituteOutAllOccurencesOfBodyVar + 1282
frame #3: 0x00000001067f3c5b Foundation`-[NSISEngine tryAddingDirectly:] + 144
frame #4: 0x00000001067f332f Foundation`-[NSISEngine tryToAddConstraintWithMarker:expression:integralizationAdjustment:mutuallyExclusiveConstraints:]
+ 440
frame #5: 0x00000001069f2067 Foundation`-[NSLayoutConstraint _addLoweredExpression:toEngine:integralizationAdjustment:lastLoweredConstantWasRounded:mutuallyExclusiveConstraints:]
+ 273
frame #6: 0x00000001067ea601 Foundation`-[NSLayoutConstraint _addToEngine:integralizationAdjustment:mutuallyExclusiveConstraints:] + 240
frame #7: 0x0000000109c9488d UIKit`__57-[UIView(AdditionalLayoutSupport) …Run Code Online (Sandbox Code Playgroud) 我刚刚阅读了以下帖子并尝试实施那里描述的方法:
那里描述的所有东西都可以完美运行。但!当我运行验收测试时,有一件事会破坏确定性。
这是 Github 上的 repo,帖子的作者在这里推送了他的实验(可以在页面底部的评论中找到):https : //github.com/moredip/2012-Olympics-iOS--iPad-and -iPhone--source-code/tree/kiwi-acceptance-mk1
考虑他用于点击视图的这段代码:
- (void) tapViewViaSelector:(NSString *)viewSelector{
[UIAutomationBridge tapView:[self viewViaSelector:viewSelector]];
sleepFor(0.1); //ugh
}
Run Code Online (Sandbox Code Playgroud)
...其中sleepFor有以下定义:
#define sleepFor(interval) (CFRunLoopRunInMode(kCFRunLoopDefaultMode, interval, false))
Run Code Online (Sandbox Code Playgroud)
等待一小段时间直到处理完所有动画并吸收所有可能的东西是一种幼稚的尝试(“幼稚”与作者无关,而是关于它是第一个想到的事实)已(或可能)调度到主运行循环的事件(另请参阅此评论)。
问题是这个简单的代码不能以一种确定性的方式工作。有一堆 UI 交互导致在当前编辑的文本字段的键盘消失之前按下 fx next 按钮点击,等等......
如果我只是将时间从 0.1 增加到 fx 1,所有问题都会消失,但这会导致每一次交互,例如“用文本填充文本字段...”或“点击带有标题的按钮...”都会花费一个第二!
所以我的意思不是仅仅增加这里的等待时间,而是一种使这种人为等待保证我可以继续下一步的测试用例的方法。
我希望它应该是一种更可靠的方法,可以等到所有由当前操作(所有转换/动画或任何主运行循环的东西)引起的东西都完成为止。
总结一下就是一个问题:
有没有办法排空/排空/浸泡所有调度到主线程及其运行循环的东西,以确保主线程空闲并且其运行循环是“空的”?
这是我最初的解决方案:
// DON'T like it
static inline void runLoopIfNeeded() {
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFRunLoopRef/Reference/reference.html
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource);
// DON'T like it
if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, …Run Code Online (Sandbox Code Playgroud) ios ×6
objective-c ×3
iphone ×2
llvm ×2
macos ×2
uiview ×2
animation ×1
automation ×1
c++ ×1
callstack ×1
clang ×1
cocoa ×1
frank ×1
ios11 ×1
llvm-clang ×1
runloop ×1
swift ×1
uistoryboard ×1
xcode ×1
xcode8 ×1