我有一个从SHOUTcast服务器播放流音频的应用程序.当应用程序位于前台并且禁用自动锁定时,一切正常.该应用程序也可以在后台播放音频,此功能在iOS 6和iOS 7上一直运行良好.但现在我的用户报告说,在升级到iOS 8后大约10分钟后,背景音频停止.
我可以通过在iOS 8上运行应用程序来自己重现问题.由于应用程序本身非常复杂,我做了一个简单的演示来显示问题.我正在使用Xcode 6和Base SDK设置为iOS 8.我已经在我的Info.plist中向UIBackgroundModes添加了音频.有谁知道下面的代码有什么问题?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *streamingURL = [NSURL URLWithString:@"http://www.radiofmgold.be/stream.php?ext=pls"];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:streamingURL];
[self setPlayerItem:playerItem];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
[player setAllowsExternalPlayback:NO];
[self setPlayer:player];
[player play];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
return YES;
}
Run Code Online (Sandbox Code Playgroud) 我最近为我的应用推出了iOS 7更新,并实现了Flurry Analytics并启用了崩溃报告.我最近注意到一些用户遇到了崩溃.使用Flurry我可以在应用程序崩溃时检索堆栈跟踪以追踪问题.
好吧,我当然熟悉崩溃报告,并且已经修复了之前使用它们的错误,从iTunes Connect或邮件中获取它们并简单地在Xcode中对它们进行符号化.然而,我没有成功使用Flurry做到这一点.
我尝试了什么:
在Flurry上查看堆栈跟踪时,这就是我得到的:
正如您所看到的,很多线条都是完美的象征,其他线条则象征着<redacted>.一些研究告诉我Apple在iOS 6和7中剥离了很多调试符号.
我尝试的第一件事是上传我自己的dSYM文件.Flurry报告已保存dSYM文件,并使用dSYM文件再次对崩溃报告进行符号化.然而,堆栈跟踪仍然与没有dSYM完全相同.
没问题,我想,我可以尝试下载崩溃报告并使用Xcode对其进行符号化.点击下载为我提供了一个文件(没有扩展名,所以我将其重命名为.crash):
Hardware Model: iPhone3,1
Process: RadioPlayer [2965]
Path: /var/mobile/Applications/E4DD7DA6-4450-4538-A1E2-AE23139FAC10/RadioPlayer.app/RadioPlayer
Identifier: *******
Version: 1.2.0
Code Type: ARM
Parent Process: launchd [1]
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x548a000
Crashed Thread: 2
Thread 0:
0 libsystem_kernel.dylib 0x3aa67a8c _mach_msg_trap + 20
1 CoreFoundation 0x3015e7cb <redacted> + 154
2 CoreFoundation 0x3015cf37 <redacted> + 854
3 CoreFoundation 0x300c7ce7 _CFRunLoopRunSpecific + 522
4 CoreFoundation 0x300c7acb _CFRunLoopRunInMode + 106
5 …Run Code Online (Sandbox Code Playgroud) 我最近发现并重现了由于使用asyncio.wait导致的内存泄漏。具体来说,我的程序定期执行某些函数,直到stop_event设置为止。我将程序简化为下面的代码片段(减少超时以更好地演示问题):
async def main():
stop_event = asyncio.Event()
while True:
# Do stuff here
await asyncio.wait([stop_event.wait()], timeout=0.0001)
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
虽然这对我来说看起来无害,但事实证明这里存在内存泄漏。如果执行上面的代码,您将看到内存使用量在几分钟内增长到数百 MB。这让我很惊讶,并花了很长时间才找到。我期望在超时后,我正在等待的任何内容都会被清理(因为我自己没有保留任何对它的引用)。然而,事实证明并非如此。
使用gc.get_referrers,我能够推断每次调用时asyncio.wait(...),都会创建一个新任务,该任务保存对返回的对象的引用stop_event.wait(),并且该任务将永远保留。具体来说,len(asyncio.all_tasks())随着时间的推移不断增加。即使超时了,任务仍然存在。只有在调用时,stop_event.set()这些任务才会立即完成,并且内存使用量才会急剧减少。
发现这一点后,文档中的这条注释让我尝试使用asyncio.wait_for代替:
与 wait_for() 不同,wait() 在发生超时时不会取消 future。
事实证明,它的表现确实如我所料。超时后不会保留任何引用,内存使用量和任务数量保持不变。这是没有内存泄漏的代码:
async def main():
stop_event = asyncio.Event()
while True:
# Do stuff here
try:
await asyncio.wait_for(event.stop_event(), timeout=0.0001)
except asyncio.TimeoutError:
pass
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
虽然我很高兴这个问题现在已经解决了,但我不太理解这种行为。如果超过了超时时间,为什么要让这个任务保留一个引用呢?这似乎是造成内存泄漏的一个秘诀。关于不取消期货的说明我也不清楚。如果我们不明确取消 future,但我们只是不让任务在超时后保留引用,该怎么办?那不是也可以吗?
如果有人能对此有所启发,我们将不胜感激。多谢!
我正在开发一个iPad应用程序,我目前正在努力寻找多线程的最佳方法.让我用一个简单的例子来说明这一点:
我有一个包含2个子视图的视图,一个目录选择器和一个图库,其中包含所选目录中所有图像的缩略图.由于"下载"并生成这些缩略图可能需要很长时间才需要多线程,因此视图的交互和更新不会被阻止.
这就是我已经尝试过的:
[self performSelectorInBackground:@selector(displayThumbnails :) withObject:currentFolder];
这工作正常,因为用户交互没有被阻止,但是当用户在第一个文件夹仍在加载时点击另一个文件夹时,它很可能失败.两个线程试图访问相同的视图和变量,这导致彼此搞乱正确执行.当用户点击另一个文件夹时,displayThumbnails当前加载的文件夹应该被中止.我没有找到任何办法这样做..
NSThreads
我试过这个但是遇到了与第一种方法几乎相同的问题,我没有找到一种(简单的)方法来取消正在进行的方法.(是的,我知道[aThread cancel]但没有办法'恢复'线程).也许我应该NSThread继承并实现我自己的isRunning等方法?但是,有没有更好的方法或第三(甚至第四和第五)选项我忽略?
我认为这是一个相当简单的例子,我认为没有子类化可能有更好的解决方案NSThread.那么,你会做什么?请你的意见!
我继承了UICollectionViewLayout.到现在为止还挺好.
但是,我有一些比屏幕更宽的单元格,有时这些单元格在滚动时会消失.当你滚动更多时,它们会神奇地重新出现在应有的位置.我可以向你展示我的代码,但我认为它没有任何问题,因为它在90%的情况下有效.但是,真正大的单元格(超过屏幕大小的两倍)有时会消失.
NSMutableArray* attributes = [NSMutableArray array];
for (int section=0; section < [[self collectionView] numberOfSections]; section++) {
[attributes addObject:[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]];
for (int row=0; row < [[self collectionView] numberOfItemsInSection:section]; row++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:row inSection:section];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
}
return attributes;
Run Code Online (Sandbox Code Playgroud)
我还有这些帖子:UICollectionView的单元格消失,UICollectionView中的大单元格在单元格仍然显示时被删除 但是,没有提到解决方案.任何人都可以帮我吗?这可能是Apple的问题吗?如果是的话,我有什么办法可以自己解决吗?
我有一个带有1的故事板UIViewController,持有1 UIView包含许多嵌套的UIViews.我将View Controller子类化为实现此方法:
- (BOOL)shouldAutorotateToInterfaceOrientation: UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Run Code Online (Sandbox Code Playgroud)
我还补充道
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeLeft</string>
Run Code Online (Sandbox Code Playgroud)
到了Info.plist.
在主UIView的viewDidLoad中我这样做:
PASectionView* sectionView = [[PASectionView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 180)];
[self addSubview:sectionView];
Run Code Online (Sandbox Code Playgroud)
问题是控制只有756像素宽而不是预期的1024.有关详细信息,请参阅下面的屏幕截图.
我一直在网上搜索,但我无法找到解决这个令人沮丧的问题的方法.我正在使用Xcode 4.5和iOS5.1设置为基本SDK.
编辑 它通过用边界替换框架来工作.但是我不明白发生了什么,所以它不适用于帧大小.
在我的应用程序的最新版本中,一些用户遇到了我无法重现的崩溃.目前只有Samsung运行Lollipop的设备存在问题,但这可能只是巧合.在分析了堆栈跟踪和相关代码之后,我认为我可能已经找到了罪魁祸首.为了测试我的假设,我将代码简化为以下代码段:
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button b = new Button(this);
b.setText("Click me!");
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Handler().post(new Runnable() {
@Override
public void run() {
// This is the callback method
Log.d("TAG", "listenerNotified");
}
});
}
});
setContentView(b);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("TAG", "onDestroy");
}
}
Run Code Online (Sandbox Code Playgroud)
每次我通过首先点击Click me按钮然后再按下后退按钮listenerNotified来测试上述应用程序之前,都会打印到控制台onDestroy().
但我不确定我是否可以依赖这种行为.Android对上述场景有任何保证吗?我可以安全地假设我的命令Runnable总是会被执行, …
java multithreading android android-lifecycle android-activity
我最近偶然发现了一些Objective-C代码中的Deallocation问题.之前讨论过Block_release中的 Stack Overflow在后台线程上释放UI对象时讨论了这个主题.我想我理解这个问题及其含义,但我确定我想在一个小小的测试项目中重现它.我首先创建了自己的SOUnsafeObject(=一个应该总是在主线程上释放的对象).
@interface SOUnsafeObject : NSObject
@property (strong) NSString *title;
- (void)reloadDataInBackground;
@end
@implementation SOUnsafeObject
- (void)reloadDataInBackground {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
self.title = @"Retrieved data";
});
sleep(3);
});
}
- (void)dealloc {
NSAssert([NSThread isMainThread], @"Object should always be deallocated on the main thread");
}
@end}]
Run Code Online (Sandbox Code Playgroud)
现在,正如预期的那样,如果由于断言失败,我在3秒[[[SOUnsafeObject alloc] init] reloadDataInBackground];内application:didFinishLaunching..将应用程序内部崩溃.拟议的修复似乎有效.即如果我将实现更改reloadDataInBackground为:应用程序不再崩溃:
__block SOUnsafeObject *safeSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
safeSelf.title = @"Retrieved data";
safeSelf …Run Code Online (Sandbox Code Playgroud) 如何在我的应用程序中创建类似文件夹的动画?我希望在动画方面做类似于any.do列表的事情.我点击一个标题,下面的所有信息向下滚动,并出现一个新信息(如文件夹或手风琴).
做这个的最好方式是什么?
例:
Title
text 1
text 2
text 3
tap on title ->
Title
new text below title
text 1
text 2
text 3
Run Code Online (Sandbox Code Playgroud)