我有一个工作的应用程序,我正在努力将其转换为Xcode 4.2中的ARC.其中一个预检警告涉及self强烈捕获导致保留周期的块.我已经制作了一个简单的代码示例来说明问题.我相信我理解这意味着什么,但我不确定实现这种情况的"正确"或推荐方法.
代码示例:
// code sample
self.delegate = aDelegate;
self.dataProcessor = [[MyDataProcessor alloc] init];
self.dataProcessor.progress = ^(CGFloat percentComplete) {
[self.delegate myAPI:self isProcessingWithProgress:percentComplete];
};
self.dataProcessor.completion = ^{
[self.delegate myAPIDidFinish:self];
self.dataProcessor = nil;
};
// start the processor - processing happens asynchronously and the processor is released in the completion block
[self.dataProcessor startProcessing];
Run Code Online (Sandbox Code Playgroud)
问题:我在做什么"错误"和/或如何修改它以符合ARC惯例?
我将我的应用程序转换为ARC,并注意到在我的一个视图控制器中分配的对象在该视图控制器被解除分配时没有被解除分配.花了一段时间才弄清楚原因.我在调试时为我的项目启用了Zombie Objects,结果证明这是原因.考虑以下应用程序逻辑:
1)用户调用动作RootViewController,导致a SecondaryViewController通过创建和呈现presentModalViewController:animated.
2)SecondaryViewController包含ActionsController一个NSObject子类.
3)ActionsController通过NSNotificationCenter初始化时观察通知,并在取消分配时停止观察.
4)用户解雇SecondaryViewController返回RootViewController.
关闭"启用僵尸对象",上面的工作正常,所有对象都被取消分配.启用Zombie Objects on ActionsController即使SecondaryViewController已取消分配,也不会取消分配.
这导致我的应用程序中的问题b/c NSNotificationCenter继续向其发送通知,ActionsController并且生成的处理程序导致应用程序崩溃.
我创建了一个简单的应用程序,在https://github.com/xjones/XJARCTestApp上说明了这一点.查看控制台日志,启用/启用"启用僵尸对象"以验证这一点.
问题(S)
编辑#1:根据凯文的建议,我已经将其提交给Apple和openradar,网址为http://openradar.appspot.com/10537635.
编辑#2:澄清一个好的答案
首先,我是一位经验丰富的iOS开发人员,我完全理解ARC,僵尸对象等.如果我遗漏了某些东西,当然,我很欣赏任何照明.
其次,这种特定崩溃的解决方法是actionsController在secondaryViewController解除分配时作为观察者删除.我还发现如果我明确设置actionsController = nil什么时候secondaryViewControllerdealloc'ed它将被dealloc'ed.这两个都不是很好的解决方法b/c它们实际上要求你使用ARC但是代码好像你没有使用ARC(例如在dealloc中明确地使用nil iVars).特定的解决方案也无法确定何时这会成为其他控制器中的问题,因此开发人员确定地知道何时/如何解决此问题.
一个好的答案将解释如何确定性地知道你需要在使用ARC + NSZombieEnabled时对某个对象做一些特殊的事情,这样它就可以解决这个具体的例子并且通常也适用于整个项目而不会留下其他类似的潜力问题.
完全有可能没有好的答案,因为这可能是XCode中的一个错误.
谢谢大家!
以下代码在iOS 5/6中运行良好.在iOS 7中,它看起来像这样(红色椭圆形用于强调).

码:
if ([MFMessageComposeViewController canSendText]) {
self.messageComposer = [MFMessageComposeViewController new];
self.messageComposer.recipients = @[number];
self.messageComposer.messageComposeDelegate = self;
[self presentViewController:self.messageComposer
animated:YES
completion:nil];
}
Run Code Online (Sandbox Code Playgroud)
问题:这是简单的代码.是否有一些其他外部属性,可能是呈现视图控制器,正在影响这个?任何人都有修复或解决方法?
谢谢.
我在应用程序商店中有一个应用程序,并使用日志服务来获取崩溃日志和相关的日志数据.我看到一个间歇性的崩溃(受影响的用户数低,每个用户的崩溃次数低),但令我感到困惑.
这些崩溃中发生的事情如下:
应用程序启动并初始化Core Data堆栈
应用程序尝试使用以下代码将SQL存储添加到NSPersistentStoreCoordinator(storeURL有效):
NSDictionary *options = @{
NSMigratePersistentStoresAutomaticallyOption : @(YES),
NSInferMappingModelAutomaticallyOption : @(YES)
};
sqlStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options
error:&error];
Run Code Online (Sandbox Code Playgroud)添加此商店时会发生以下错误之一:
NSError:
Domain = NSCocoaErrorDomain
Code = 256"操作无法完成.(Cocoa错误256.)"
UserInfo = 0x1dd946a0 {NSUnderlyingException =授权被拒绝,NSSQLiteErrorDomain = 23}
要么
NSError:
Domain = NSCocoaErrorDomain
Code = 256"无法完成操作.(Cocoa error 256.)"
UserInfo = 0xc6525d0 {NSUnderlyingException = disk I/O error,NSSQLiteErrorDomain = 10}
在这种情况下,应用程序将崩溃b/c应用程序运行所需的SQL存储.我可以尝试通过尝试新的storeURL来优雅地处理此故障,但我不希望用户丢失现有数据.此外,我从未亲自重现此问题,并且基于受影响的用户数量和崩溃日志,我认为这是一个影响较小的问题,并且不会在随后的应用程序启动时重复出现.
我希望那里有一位核心数据专家,提供一些关于如何调试和预防/处理这些条件的建议.我的核心数据堆栈初始化代码直接来自xcode项目生成器,我排除了任何并发问题,因为持久性存储协调器只初始化一次(启动时),并且此错误发生在此初始化中.
很高兴提供更多相关的代码/信息.
谢谢!
编辑:改变了标题.我当时不知道它,但这是一个重复的为什么我崩溃MKMapView释放后,如果我不再使用它?
这个问题类似于为什么在使用ARC + NSZombieEnabled时对象没有dealloc'ed,但足够不同以至于我认为值得抛弃,以防任何人理解并可以向我解释发生了什么.另一个问题可能是XCode错误,所以我认为这可能是类似的.
场景:
RootViewController有tableView一堆显示项目detailViewController包含另一个单元格的模态tableViewdetailViewController包含MKMapView显示项目的位置mapView.delegate = detailViewControllerdetailViewController在此之后不久,应用程序崩溃b/c MKMapView发送mapView:viewForAnnotation:到现在dealloc'ed detailViewController.此崩溃在具有临时分发构建的用户设备上重新编写,因此该问题与此无关NSZombieEnabled.
我能够通过添加以下内容来解决崩溃:
_mapView.delegate = nil;
Run Code Online (Sandbox Code Playgroud)
到包含mapView 的dealloc方法tableViewCell.
问题:为什么有必要在细胞被解除分配时使代表无效?mapView当细胞被解除分离时,似乎应该由ARC解除分离,这样就不必要了.没有代表是好的做法,但我认为在这种情况下不需要.
编辑:两者的所有子视图detailViewController和UITableViewCells声明(nonatomic, strong)属性ala:
@property (nonatomic, strong) MKMapView * mapView;
Run Code Online (Sandbox Code Playgroud)
编辑2:猜猜我需要更好地阅读文档.@fluchtpunkt是对的.以下是MKMapView文档中的相关信息:
在释放已设置委托的MKMapView对象之前,请记住将该对象的委托属性设置为nil.您可以在dealloc方法中处理地图视图.
在iOS 6中,viewWillUnload并viewDidUnload已被取消,UIViewControllers不再卸载观点,即内存警告时不显示在屏幕上.该视图控制器编程指南对如何手动还原此行为的一个例子.
这是代码示例:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Add code to clean up any of your own resources that are no longer necessary.
if ([self.view window] == nil)
{
// Add code to preserve data stored in the views that might be
// needed later.
// Add code to clean up other strong references to the view in
// the view hierarchy.
self.view = nil;
}
}
Run Code Online (Sandbox Code Playgroud)
代码示例下面是以下注释:
下次访问视图属性时,视图将与第一次完全重新加载.
这里有一个明显的缺陷.如果未加载其视图的视图控制器收到内存警告,它将在该行中加载其视图if ([self.view window] …
考虑以下:
NSFetchRequest *request = [[NSFetchRequest Alloc] init];
request.entity = [NSEntityDescription entityWithName:@"Person" inContext:_MOC];
request.propertiesToFetch = [NSArray arrayWithObject:@"Name"];
NSError *error = nil;
NSArray *results = [_MOC executeFetchRequest:request error:&error];
Run Code Online (Sandbox Code Playgroud)
这将返回一个Person对象数组.我想要的是Person.name来自这些对象的值数组.目前我走结果数组,提取名称并构建一个新数组.有更清洁,更快的方法吗?我已经考虑过改变request.resultType,NSDictionaryResultType但这并没有太大的收获,因为我仍然需要将字典数组转换为我需要的数组.
我已经实现了上面的解决方案,所以真的在寻找更好的方法.如果正确答案是"没有更好的方法"那就没关系,只要确保我没有错过任何东西.谢谢!
编辑:在考虑这个问题时,我质疑我需要一个值数组而不仅仅是使用托管对象数组.在任何情况下,如果那里有一个,仍然会很感激.
在某些情况下,并不是每一次,当我的应用程序给出了使用模态视图控制器presentModalViewController:animated:与modalTransitionStyle设置为UIModalTransitionStyleFlipHorizontaliPhone的主屏幕是动画背后可见.大多数情况下,背景是预期的黑色.我设置window或rootViewController(a UITabBarController)没有异常.我将应用程序用户界面涂黑了,但是当转换正在进行时,您可以在使用iPhone 4拍摄的屏幕截图中看到问题.
什么会导致这个?即使我想要这种行为,我也不知道怎么做.
编辑:这个屏幕截图由测试人员发送给我,我没有自己重新编写.他们告诉我它发生在特定的应用程序会话期间,一旦发生,它就发生在所有转换中.当他们退出/重新启动应用程序时,它没有再次发生,他们从那时起就没有看到它.我想知道是否需要关注它(即我可以在代码中阻止它).
编辑2:此应用程序不使用IB.所有控制器/视图都是用代码创建的.

您将看到一个空白屏幕(窗口).测试项目以演示此错误/问题:http://github.com/chetanpungaliya/iOS-5-TestModal
我正在使用AVFoundation类在我的应用程序中实现自定义相机.我只捕捉静止图像,而不是视频.我有一切工作,但我被一些东西困扰.我会在捕获静止图像时考虑设备方向,并适当地设置视频连接的videoOrientation.代码段:
// set the videoOrientation based on the device orientation to
// ensure the pic is right side up for all orientations
AVCaptureVideoOrientation videoOrientation;
switch ([UIDevice currentDevice].orientation) {
case UIDeviceOrientationLandscapeLeft:
// Not clear why but the landscape orientations are reversed
// if I use AVCaptureVideoOrientationLandscapeLeft here the pic ends up upside down
videoOrientation = AVCaptureVideoOrientationLandscapeRight;
break;
case UIDeviceOrientationLandscapeRight:
// Not clear why but the landscape orientations are reversed
// if I use AVCaptureVideoOrientationLandscapeRight here the pic ends up upside down …Run Code Online (Sandbox Code Playgroud) ios ×8
iphone ×3
core-data ×2
objective-c ×2
ios5 ×1
ios6 ×1
ios7 ×1
mfmessagecomposeviewcontroller ×1
xcode4.2 ×1