我正在尝试为本地通信构建JavaScript。为此,我需要在JavaScript调用某个类时动态地执行该方法。
我对NSInvocation获取返回值有疑问。使用getReturnValue时,应用程序由于僵尸而崩溃。指示僵尸来自调用方法的返回值的调用。
如果我将 public static void setCourseList(String courseDescription, String courseName, LocalTime courseStart, LocalTime courseEnd, LocalDate courseDate, DayOfWeek courseDay) {
Connection conn = null;
try {
// db parameters
// path to db relative to run time directory
String url = "jdbc:sqlite:Holiday.db";
String sqlInsertCourse = "INSERT INTO COURSE (Name,Start,End,Date,Day,Description) VALUES (?, ?,?, ?,?, ?,);";
conn = DriverManager.getConnection(url);
System.out.println("Connected");
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sqlInsertCourse);
pstmt.setString(1, courseName);
String courseStartString = courseStart.toString();
pstmt.setString(2, courseStartString);
java.sql.Time courseEndTime = Time.valueOf(courseEnd);
pstmt.setTime(3, courseEndTime);
java.sql.Date courseDateDate = java.sql.Date.valueOf(courseDate);
pstmt.setDate(4, courseDateDate);
String courseDayString = courseDay.toString();
pstmt.setString(5, courseDayString);
pstmt.executeUpdate();
pstmt.close();
System.out.println("Connection to SQLite has been established.");
// create tables if they do not exists
stmt.execute(sqlInsertCourse);
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
}
行注释掉,则应用程序不会中断。
我当前正在调用的测试方法会返回{{1} 如果我使调用的选择器方法实现返回一个@@ firstsecond之类的文字字符串,则应用程序也不会中断。
为什么已经执行了调用方法并返回了一个字符串,为什么它需要以任何方式对其进行引用。不是将返回的字符串复制到[invocation getReturnValue:&result];
。
(NSString *)
尽管 Instruments 中的选择器不同,但结果相同。从这张照片中我了解了我告诉你的。我没有使用乐器的经验。
答案 0 :(得分:1)
您是ARC的受害者,但不知道NSInvocation
的工作方式是通过另一个指针间接修改result
。这是here中描述的已知问题。
发生的情况是,生成的对象间接变为等于result
,但是ARC无法识别该对象并且永远不会保留它。
NSString
是一个类集群。它的有效含义是根据字符串的创建和使用方式在更改下的实现。在obj-c中与之交互时,它的细节被隐藏了,而Apple付出了很多努力,以使其与iOS开发人员无缝连接。您的情况有点特殊。
通常,您会得到:
__NSCFConstantString
(例如@"constant"
)-应用程序生存期的字符串常量,对于您来说,发生可以正常工作,但您从不 NSTaggedPointerString
(例如[[@"a"] mutableCopy] copy]
)-具有内部查找表的优化短字符串。__NSCFString
(例如[@"longString" mutableCopy] copy]
)长字符串CoreFoundation
表示。随时NSString
可能会更改其下的实现,因此您永远不应对此做任何假设。返回后,情况3将立即超出范围并在下一个运行循环中被释放,情况1将永远不会被释放,情况2(?),但可以肯定的是在下一个运行循环中仍然存在。
因此,从根本上说,ARC不够聪明,无法将可能已释放的对象与id result
关联,从而遇到了问题。
如何解决?
使用以下之一:
1。
void *tempResult;
[invocation getReturnValue:&tempResult];
id result = (__bridge id) tempResult;
2。
__unsafe_unretained id tempResult;
[invocation getReturnValue:&tempResult];
result = tempResult;
修改
如@newacct在他的评论getReturnValue:
中指出的,weak
指针未注册,因此在这种情况下不适当。释放对象时,指针不会归零。
<罢工> 3。
__weak id tempResult;
[invocation getReturnValue:&tempResult];
result = tempResult;