- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
所以与此类似recently posted question ,我在将 Amazon 的 AWS Obj-C 库与我的 Swift 应用程序集成时遇到问题。我有一个 NSOperation
,它使用 Transfer Utility library 处理文件上传到 S3其中包括对后台文件传输的支持。最近发布了我们的应用程序后,我发现当应用程序返回前台时重新连接进度处理程序的代码发生了一些崩溃。代码改编自their Obj-C example :
- (void)viewDidLoad {
[super viewDidLoad];
...
AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];
[transferUtility
enumerateToAssignBlocksForUploadTask:^(AWSS3TransferUtilityUploadTask *uploadTask, __autoreleasing AWSS3TransferUtilityUploadProgressBlock *uploadProgressBlockReference, __autoreleasing AWSS3TransferUtilityUploadCompletionHandlerBlock *completionHandlerReference) {
NSLog(@"%lu", (unsigned long)uploadTask.taskIdentifier);
// Use `uploadTask.taskIdentifier` to determine what blocks to assign.
*uploadProgressBlockReference = // Reassign your progress feedback block.
*completionHandlerReference = // Reassign your completion handler.
}
downloadTask:^(AWSS3TransferUtilityDownloadTask *downloadTask, __autoreleasing AWSS3TransferUtilityDownloadProgressBlock *downloadProgressBlockReference, __autoreleasing AWSS3TransferUtilityDownloadCompletionHandlerBlock *completionHandlerReference) {
NSLog(@"%lu", (unsigned long)downloadTask.taskIdentifier);
// Use `downloadTask.taskIdentifier` to determine what blocks to assign.
*downloadProgressBlockReference = // Reassign your progress feedback block.
*completionHandlerReference = // Reassign your completion handler.
}];
}
我的 Swift 版本在尝试取消引用 newProgressPointer
时因 EXC_BAD_ACCESS KERN_INVALID_ADDRESS
而崩溃:
// Swift 2.3
class AttachmentQueue: NSOperationQueue {
...
/**
Recreates `UploadOperation` instances for any that were backgrounded by the user leaving the
app.
*/
func addBackgroundedOperations() {
let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
transferUtility.enumerateToAssignBlocksForUploadTask({ (task, progress, completion) -> Void in
guard let operation = UploadOperation(task: task, oldProgressPointer: progress, oldCompletionPointer: completion) else { return }
self.addOperation(operation)
}, downloadTask: nil)
}
}
/// An `UploadOperation` is an `NSOperation` that is responsible for uploading an attachment asset
/// file (photo or video) to Amazon S3. It leans on `AWSS3TransferUtility` to get the actual
/// uploading done.
class UploadOperation: AttachmentOperation {
...
/// An `AutoreleasingUnsafeMutablePointer` to the upload progress handler block.
typealias UploadProgressPointer = AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityTask, NSProgress) -> Void)?>
/// An `AutoreleasingUnsafeMutablePointer` to the upload completion handler block.
typealias UploadCompletionPointer = AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityUploadTask, NSError?) -> Void)?>
/**
A convenience initializer to be used to re-constitute an `AWSS3TransferUtility` upload task that
has been moved to the background. It should be called from `.enumerateToAssignBlocksForUploadTask()`
when the app comes back to the foreground and is responsible for re-hooking-up its progress and
completion handlers.
- parameter task: The `AWSS3TransferUtilityTask` that needs re-hooking-up.
- parameter oldProgressPointer: An `AutoreleasingUnsafeMutablePointer` to the original progress handler.
- parameter oldCompletionPointer: An `AutoreleasingUnsafeMutablePointer` to the original completion handler.
*/
convenience init?(task: AWSS3TransferUtilityUploadTask, oldProgressPointer: UploadProgressPointer, oldCompletionPointer: UploadCompletionPointer) {
self.init(attachment: nil) // Actual implementation finds attachment record
// Re-connect progress handler
var progressBlock: AWSS3TransferUtilityProgressBlock = self.uploadProgressHandler
let newProgressPointer = UploadProgressPointer(&progressBlock)
print("newProgressPointer", newProgressPointer)
print("newProgressPointer.memory", newProgressPointer.memory) // Throws EXC_BAD_ACCESS KERN_INVALID_ADDRESS
oldProgressPointer.memory = newProgressPointer.memory
// Re-connect completion handler
var completionBlock: AWSS3TransferUtilityUploadCompletionHandlerBlock = self.uploadCompletionHandler
let newCompletionPointer = UploadCompletionPointer(&completionBlock)
oldCompletionPointer.memory = newCompletionPointer.memory
}
/**
Handles file upload progress. `AWSS3TransferUtility` calls this repeatedly while the file is
uploading.
- parameter task: The `AWSS3TransferUtilityTask` for the current upload.
- parameter progress: The `NSProgress` object for the current upload.
*/
private func uploadProgressHandler(task: AWSS3TransferUtilityTask, progress: NSProgress) {
// We copy the `completedUnitCount` to operation but it would be nicer if we could just
// reference the one passed to us instead of having two separate instances
self.progress.completedUnitCount = progress.completedUnitCount
// Calculate file transfer rate using an exponential moving average, as per https://stackoverflow.com/a/3841706/171144
let lastRate = self.transferRate
let averageRate = Double(progress.completedUnitCount) / (NSDate.timeIntervalSinceReferenceDate() - self.uploadStartedAt!)
self.transferRate = self.smoothingFactor * lastRate + (1 - self.smoothingFactor) * averageRate;
progress.setUserInfoObject(self.transferRate, forKey: NSProgressThroughputKey)
}
/**
Handles file upload completion. `AWSS3TransferUtility` calls this when the file has finished
uploading or is aborted due to an error.
- parameter task: The `AWSS3TransferUtilityTask` for the current upload.
- parameter error: An instance of `NSError` if the upload failed.
*/
private func uploadCompletionHandler(task: AWSS3TransferUtilityUploadTask, error: NSError?) {
...
}
...
}
为什么指针 memory
引用在创建后立即无效?
作为 iOS 开发的新手并且没有 Obj-C(或其他非内存管理语言)的实际经验,我有点迷茫。如果有人能阐明一些观点,我们将不胜感激。
编辑:
enumerateToAssignBlocksForUploadTask(…)
的 Swift 方法签名
/**
Assigns progress feedback and completion handler blocks. This method should be called when the app was suspended while the transfer is still happening.
@param uploadBlocksAssigner The block for assigning the upload pregree feedback and completion handler blocks.
@param downloadBlocksAssigner The block for assigning the download pregree feedback and completion handler blocks.
*/
public func enumerateToAssignBlocksForUploadTask(uploadBlocksAssigner: ((AWSS3TransferUtilityUploadTask, AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityTask, NSProgress) -> Void)?>, AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityUploadTask, NSError?) -> Void)?>) -> Void)?, downloadTask downloadBlocksAssigner: ((AWSS3TransferUtilityDownloadTask, AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityTask, NSProgress) -> Void)?>, AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityDownloadTask, NSURL?, NSData?, NSError?) -> Void)?>) -> Void)?)
最佳答案
我认为您不应该需要这些指针中的大部分(或任何)。看看 Swift example code from AWS看看它是否不符合您的要求。
以您现有的方式创建指针在 Swift 中并不安全。这可能比您需要的信息多得多(您不必如此努力地工作),但可能会发生这种情况(在这种情况下,这种解释并不完全正确,但这是可能发生的事情,所以值得了解):
progressBlock
。progressBlock
不再在范围内的任何其他地方访问。progressBlock
。我说这感觉不对,因为还有对闭包的第二个引用无论如何都应该使闭包保持事件状态,但通常,以这种方式使用构造函数创建指针是非常危险的。
(这可能会崩溃,因为您无法打印
@convention(block)
闭包;我从未尝试过这样做。这不是很正常尝试打印的东西。)
无论如何,如果您确实需要做这种事情(而且我认为您不需要),您需要按照以下方式进行:
withUnsafeMutablePointer(to: self.uploadProgressHandler) { newProgressPointer in
... newProgressPointer is safe to use in this block ...
}
但通常,如果您正在转换 ObjC 代码(不是纯 C,而只是 ObjC),并且发现您必须创建很多 Unsafe
对象,您可能正在走走错了路。大多数 ObjC 事物都可以很好地桥接到 Swift,而无需 Unsafe
。
关于ios - 为什么我刚创建的指针抛出 KERN_INVALID_ADDRESS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41854286/
我不确定为什么会收到此错误,而且我无法查明原因。虽然这只发生在设备上,但模拟器按预期运行无错误。谁能理解这个崩溃日志? Exception Type: EXC_BAD_ACCESS (SIGSEGV
我经常崩溃,你能帮我找出解决办法吗 Incident Identifier: BC2870F3-4119-462B-9B2E-2236E403E7C2 CrashReporter Key: 7d9
我在尝试运行调试器时不断收到此错误: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INV
我有时会遇到这个错误: Thread : Crashed: com.apple.root.default-priority 0 libobjc.A.dylib 0x00
谁能告诉我如何解决我的应用程序中出现的崩溃。我无法找到为什么会发生这次崩溃。我没有得到任何线索。我搜索我的项目以找到“objectIsKindOfClass”,但我没有使用过这种方法。 最佳答案 为了
所以与此类似recently posted question ,我在将 Amazon 的 AWS Obj-C 库与我的 Swift 应用程序集成时遇到问题。我有一个 NSOperation,它使用 T
我有一个奇怪的问题。我收到一个错误报告,说该应用程序崩溃与方向更改有关。问题是我还没有在应用程序代码中注册任何定向事件。我唯一与方向变化有关的是: - (BOOL)shouldAutorotateTo
我在发布的应用程序中偶尔会发生崩溃,并且从崩溃报告中知道它发生的行和崩溃类型 - EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS - 但我不知道内存如何变得
使用 Crashlytics,我看到我的一小部分用户因错误 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 而崩溃,在以下行中: [[UIApplication sharedA
我正在用 c 语言编写一个程序,该程序严重依赖于正则表达式,我执行它们的机制在 99% 的时间都有效,但它每隔一段时间就会让程序崩溃,我很困惑为什么会这样。 New_Sifter() 采用其正则表达式
我收到这个错误,这可能是什么??? 程序收到信号 EXC_BAD_ACCESS,无法访问内存。原因:KERN_INVALID_ADDRESS 地址:0x0000000000000000strlen (
我看到类方法的 EXC_BAD_ACCESS KERN_INVALID_ADDRESS。 据我所知,我不应该在类/静态方法中看到这一点。 我错过了什么吗? 堆栈跟踪: Thread : Crashed
我使用 Xcode 6.3.2 开发了一个 iPad 应用程序。我将我的应用程序提交到 App Store 进行审核,但由于崩溃而被拒绝。以下是来自 iTunes 的崩溃报告。 Incident Id
我的应用程序通过 Xcode 在 Debug模式下运行良好,但每当通过 TestFlight 下载时,它就会崩溃并出现以下错误:EXC_BAD_ACCESS KERN_INVALID_ADDRESS
MyApp 在 98% 的情况下运行良好,但有时会崩溃。太随意了。 崩溃报告显示以下内容。 Thread : Crashed: com.apple.main-thread 0 libobjc.A.d
iPhone 操作系统上的 KERN_INVALID_ADDRESS 和 KERN_PROTECTION_FAILURE 有什么区别? 我有两个来自临时 Beta 测试人员的崩溃报告,它们相隔 5 分
我不断通过 Crashlytics 收到有关此崩溃的报告,但我不知道如何找出问题所在,因为堆栈跟踪不会在任何地方触及我的代码。我能做些什么?如何找到问题的根源? EXC_BAD_ACCESS KERN
我在 Unity (2019.2.16f1) 上开发了一个游戏,我有一个 大问题 : 1 秒后提交到 App Store 的构建崩溃(启动时) 更多信息: 我编写了一些 c# 脚本,但大部分游戏都使用
我正在尝试将图像更改为黑白,这些图像是从服务调用中提供的,一旦获得图像,我就会应用黑色滤镜将它们更改为黑白。我只在 iOS 13 上遇到过这个悬空指针异常,其他 iOS 版本没有这个问题。 这是代码:
我收到以下错误。 EXC_BAD_ACCESS KERN_INVALID_ADDRESS [UITextField keyboardInputChangedSelection:] 直到这份最新的崩溃
我是一名优秀的程序员,十分优秀!