在我当前的项目中,几个视图控制器(如vc)生成operation在静态NSOperationQueue上执行的NSOperation对象(如).当操作正在等待或运行时,它将通过委托(报告operation.delegate = vc未保留)向视图控制器报告.
这些操作可能需要一段时间,同时应用程序可以取消分配视图控制器(通过弹出导航控制器的堆栈).
到目前为止,一切都是故意的.包含静态NSOperationQueue的类有一种方法可以返回操作,因此视图控制器不会保留它们.它们只是alloc/init/autoreleased并放入队列.
现在这也导致了这个问题.在视图控制器解除分配后,对NSOperation的激烈委托的任何调用都将导致错误的访问冲突.根据我的理解,无法检查指针上的对象是否已被解除分配,如本问题所述.
我能想到的一个修复是保留操作并在dealloc上将operation.delegate设置为nil.但这是我最不受欢迎的解决方案,因为它会引入许多额外的ivars /属性来跟踪.
因此,我的问题是,有没有其他方法可以解决这个问题,如果是这样,你能在这里草拟一个吗?
干杯,
EP.
解决方案:对我来说最好的方法是对Guiliano的回答略有不同:
在队列管理器中实现每个委托协议是不可行的(20多种不同的协议,使用50多种方法),因此我保留了直接委托分配.我改变的是进行分配呼叫的班级.这曾经是创建请求的类(和委托),但现在它被卸载到队列管理器.
除了将委托分配给操作之外,队列管理器还拥有辅助可变字典以跟踪委托/操作对.
每个委托实例都会调用一个[QueueManager invalidateDelegate:self]deallocation方法,然后查找属于该委托的请求并将其取消.然后还删除字典操作/委托对以允许适当地重新分配操作.
最后,当KVO观察isFinished每个操作的属性时,可变dict保持清洁,以确保所有操作保留计数在它们完成后实际解除分配.
感谢Guiliano提供使用KVO破解这一点的提示!
exc-bad-access delegation objective-c nsoperation nsoperationqueue
我正在构建一个应用程序,它将图像缓存在应用程序包的Documents目录中.为了确保目录存在,我想检查它们是否存在,如果不存在,则在应用程序启动时创建它们.
目前,我这样做didFinishLaunchingWithOptions:是这样的:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSArray *directoriesToCreate = [[NSArray alloc] initWithObjects:
@"DirA/DirA1",
@"DirA/DirA2",
@"DirB/DirB2",
@"DirB/DirB2",
@"DirC",
nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
for (NSString *directoryToCreate in directoriesToCreate) {
NSString *directoryPath = [documentsPath stringByAppendingPathComponent:directoryToCreate];
NSLog(directoryPath);
if (![[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:YES]) {
NSError *directoryCreateError = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:directoryPath
withIntermediateDirectories:YES
attributes:nil
error:&directoryCreateError];
}
}
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
在应用程序的第一次运行时 - 当没有任何目录存在时 - 应用程序运行,目录按预期创建,一切运行正常.
当应用程序终止并再次运行时,我会在fileExistsAtPath:通话时收到EXC_BAD_ACCESS信号[NSFileManager defaultManager] …
我从远程用户那里得到了这个崩溃报告,但我找不到任何有用的提示来解决这个问题,可能是一个保留问题,但我无法理解为什么因为我使用ARC.极少数用户发出此问题.我已经在模拟器和设备(iPhone 4s)上尝试了所有的东西而没有发生任何崩溃......如果我能够在我的设备上崩溃,那么找出问题是非常简单的.
有人知道如何解决这个问题吗?
Incident Identifier: F30F9C75-0FE3-4B39-AA17-209690A4787D
Hardware Model: iPod4,1
Process: Body-Language [1220]
Path: /var/mobile/Applications/2489EE05-177C-4AD1-BE3A-7B7158E13D82/Body-Language.app/Body-Language
Identifier: Body-Language
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2012-03-19 23:09:02.516 +0100
OS Version: iPhone OS 5.1 (9B176)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x6c707049
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x30d63f78 objc_msgSend + 16
1 CoreFoundation 0x30c49e90 CFRetain + 76
2 CoreFoundation 0x30c53b74 +[__NSArrayI __new::] + 48 …Run Code Online (Sandbox Code Playgroud) 我正在通过移植现有的应用程序来学习Swift.我一直坚持设置代表,无法解决问题所在.
我有一个扩展UITableViewCell的类
import UIKit
protocol SwitchCellDelegate{
func switchChanged(switchCell: SwitchCell, state: Bool)
}
class SwitchCell: UITableViewCell {
@IBOutlet var swtSelector: UISwitch
@IBOutlet var lblTitle: UILabel
var delegate: SwitchCellDelegate?
init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@IBAction func switchChanged(){
delegate?.switchChanged(self, state: swtSelector.on)
}
}
Run Code Online (Sandbox Code Playgroud)
然后在ViewController中定义为
class SettingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwitchCellDelegate {
Run Code Online (Sandbox Code Playgroud)
并在方法内
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
Run Code Online (Sandbox Code Playgroud)
我们有
case 2:
storeCredentialsCell = tableView.dequeueReusableCellWithIdentifier("StoreCredentialsCell") as? SwitchCell
if(storeCredentialsCell != nil){
...
NSLog("Setting delegate to %@ for …Run Code Online (Sandbox Code Playgroud) 在我的前几个虚拟应用程序中(为了练习而学习)我遇到了很多EXC_BAD_ACCESS,不知何故教会我Bad-Access是:你正在触摸/访问一个你不应该因为它尚未分配或取消分配的对象或者只是您无权访问它.
看看这个具有错误访问问题的示例代码,因为我试图修改一个const:
-(void)myStartMethod{
NSString *str = @"testing";
const char *charStr = [str UTF8String];
charStr[4] = '\0'; // bad access on this line.
NSLog(@"%s",charStr);
}
Run Code Online (Sandbox Code Playgroud)
虽然分段错误说:分段错误是由访问"不属于您"的内存引起的一种特定错误.它是一种帮助机制,可以防止破坏内存并引入难以调试的内存错误.每当你遇到段错误时,你就知道你在做错了记忆(这里有更多描述).
我想知道两件事.一,我是对的objective-C's EXC_BAD_ACCESS吗?我做对了吗?
第二,EXC_BAD_ACCESS and Segmentation fault同样的事情和Apple刚刚即兴创作了它的名字吗?
我遇到了一个问题,我无法理解为我的生活.我搜索了互联网,试图了解Swifts的EXC_BAD_ACCESS,但似乎没有任何帮助.
以下代码很长,但大多数时候注释都是理解相关项所需的所有信息.
我有一个类CalculatorController,其中包含以下相关方法和属性:
import UIKit
class CalculatorController: UIViewController {
// the actual `@IBOutlet` which is never accessed directly
@IBOutlet private weak var _mainDisplay: UILabel!
// an instance of `MainDisplayMicroController`
// holds a reference to `_mainDisplay`
// is used to manipulate `_mainDisplay` in a controlled way
private var mainDisplay: MainDisplayMicroController!
override func viewDidLoad() {
super.viewDidLoad()
// connects `mainDisplay` with `_mainDisplay`
mainDisplay = MainDisplayMicroController(label: _mainDisplay)
// sets `_mainDisplay`'s `text` property to "0"
mainDisplay.content = .Number(0)
//...
}
//... …Run Code Online (Sandbox Code Playgroud) 我有一个非常复杂的表视图设置,我决定使用块结构来创建和选择单元格,以简化未来的开发和更改.
我正在使用的结构如下所示:
var dataSource: [(
cells:[ (type: DetailSection, createCell: ((indexPath: NSIndexPath) -> UITableViewCell), selectCell: ((indexPath: NSIndexPath) -> ())?, value: Value?)],
sectionHeader: (Int -> UITableViewHeaderFooterView)?,
sectionFooter: (Int -> UITableViewHeaderFooterView)?
)] = []
Run Code Online (Sandbox Code Playgroud)
然后我可以在setup函数中设置表格,并使我的委托方法相当简单
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = dataSource[indexPath.section].cells[indexPath.row].createCell(indexPath:indexPath)
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource[section].cells.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return dataSource.count
}
Run Code Online (Sandbox Code Playgroud)
我之前在另一个TVC做过类似的设置
var otherVCDataSource: [[ (type: DetailSection, createCell: ((indexPath: NSIndexPath) -> UITableViewCell), …Run Code Online (Sandbox Code Playgroud) 我的应用程序与iOS5 b7和GM版本的兼容性存在问题.
问题出现在下一行代码中:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
Run Code Online (Sandbox Code Playgroud)
EXC_BAD_ACCESS在一些迭代之后,应用程序与信号崩溃.
传递的迭代次数是随机的(从2到7).
在iOS4和iOS3上一切都运行良好.
Apple的示例中出现了同样的问题:XMLPerformance Sample.
你怎么看待这件事?
10月12日我的应用程序的数千名用户将升级到iOS5,我不希望我的应用程序在AppStore中出现如此奇怪的错误.
我有一个iOS(7.1)应用程序崩溃的原因EXC_BAD_ACCESS.如果我没错,这是因为使用了已经解除分配的对象.经过一些搜索,我发现启用Zombie对象有助于确定错误行.当我使用xcode 5.1.1时,我已经完成了以下操作来启用Zombie Objects.

Enable Zombie Objects复选框,
xcode
exc-bad-access
instruments
nszombie
ios
Crashlytics在我的一个应用程序中报告了这次崩溃,无论我做什么,我都无法重现它.这种情况发生在大约5%的用户身上,所以这是一个非常重要的事情.我发布了崩溃报告的截图以及崩溃报告中提到的方法.不知道怎么解决这个问题?
这是应用程序崩溃的地方:
#pragma mark - custom transformations
-(BOOL)__customSetValue:(id<NSObject>)value forProperty:(JSONModelClassProperty*)property
{
if (!property.customSetters)
property.customSetters = [NSMutableDictionary new];
NSString *className = NSStringFromClass([JSONValueTransformer classByResolvingClusterClasses:[value class]]);
if (!property.customSetters[className]) {
//check for a custom property setter method
NSString* ucfirstName = [property.name stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[property.name substringToIndex:1] uppercaseString]];
NSString* selectorName = [NSString stringWithFormat:@"set%@With%@:", ucfirstName, className];
SEL customPropertySetter = NSSelectorFromString(selectorName);
//check if there's a custom selector like this
if (![self respondsToSelector: customPropertySetter]) {
property.customSetters[className] = [NSNull null]; // this is line 855
return NO;
}
//cache the custom setter …Run Code Online (Sandbox Code Playgroud) exc-bad-access ×10
ios ×6
objective-c ×4
swift ×3
xcode ×3
c ×1
cocoa-touch ×1
crash ×1
debugging ×1
delegates ×1
delegation ×1
iboutlet ×1
instruments ×1
ios5 ×1
jsonmodel ×1
nsoperation ×1
nsrunloop ×1
nszombie ×1
uilabel ×1
uitableview ×1
xcode6 ×1