我想将回调块从 Objective-C++ 代码传递到 C++ 对象。这非常简单,因为我可以将一个块分配给 std::function。在我的迷你示例中,一切正常,但我仍然不确定这样做是否安全。
#import "ViewController.h"
#include <functional>
std::function<void(void)> f;
@interface T : NSObject
@property (strong) NSString* value;
@end
@implementation T
- (void)dealloc {
NSLog(@"dealloc");
}
@end
@implementation ViewController
- (IBAction)storeBlock:(UIButton *)sender {
T* t = [[T alloc] init];
t.value = @"the captured obj";
f = ^void(void) { NSLog(@"This is the block with %@", t.value); };
}
- (IBAction)useBlock:(UIButton *)sender {
f();
}
- (IBAction)releaseBlock:(UIButton *)sender {
f = nullptr;
}
@end
Run Code Online (Sandbox Code Playgroud)
我了解到这些块存储在堆栈上,如果我想在块创建的范围之外使用它,我必须将其复制到堆(我在示例中没有明确这样做)。我也不确定 ARC 如何处理这种情况。“官方”允许这样做吗?我正在使用 Xcode 9.2。
概述
我正在将 C++ / ObjC++ 库移植到 Swift 包管理器。该库针对常见的 Apple 平台(iOS、macOS)。目前,可以使用xcodebuild静态库目标来构建该库。
问题
由于该库包含 C++ <> ObjC 桥接代码,因此它有一个使用 标志编译的文件-fno-objc-arc。所有其他文件均使用 ARC 编译。是否可以传递一个标志,告诉 SPM 在没有 ARC 的情况下也编译该文件?
截屏
包.swift
// swift-tools-version:5.4
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "library_name",
platforms: [
.iOS(.v13)
],
products: [
.library(
name: "library_name",
targets: ["library_name"]),
],
dependencies: [
],
targets: [
.target(
name: "library_name",
dependencies: [],
path: "./sources/",
exclude: [ …Run Code Online (Sandbox Code Playgroud) c++ objective-c++ automatic-ref-counting swift swift-package-manager
我在自己的应用程序中遇到了一个有趣的 Metal 性能问题,我只需对此示例项目进行少量调整即可重现该问题。我的视图大小约为 1600x900,如下所示:
\n\n每帧有两次绘制调用,一次用于背景,一次用于线条。背景由4个顶点组成,线条大约有2000个顶点。当场景像上面一样绘制时,Xcode 的 GPU 帧捕获告诉我整个帧需要大约 4 毫秒(!)。一些观察结果:
\n这对我来说没有意义。为什么上述变化会对帧时间产生如此巨大的影响?这是 100 倍的差异。
\n我正在 2018 Mac mini(配备 Intel UHD Graphics 630 1536 MB)上运行代码,以防万一这很重要。
\n以下是对演示项目所做的更改:
\nMTLBuffer在初始化期间创建两个sAAPLVertex quadVertices[] = { ... 4 vertices omitted ... };\nquadBuffer = [_device newBufferWithBytes:quadVertices length:4 * sizeof(AAPLVertex) MTLResourceStorageModeManaged];\n\nAAPLVertex dataVertices[] = { ... ~2000 vertices …Run Code Online (Sandbox Code Playgroud) 我保留了同一天出版的2本图书馆书籍.我在架子上看到它们,并意识到它们是相同的,除了一个是关于ObjC,一个是关于ObjC 2.0.
另外,什么是Objective-C++?
在Objective-C++中禁止将C++引用类型作为实例变量.我该如何解决这个问题?
我希望这个问题不是太傻,但标准C++中最基本的类是什么?宾语?宾语?
class MyObject : public object{ ...
Run Code Online (Sandbox Code Playgroud)
我得到"令牌之前的预期类名"
是否有显示标准c ++类继承的地图,图表或图像? 这样的东西,但对于C++?
我在iOS项目中混合了Objective-C(*.m)和Objective-C++(*.mm)源文件.当我在*.m文件中导入C++头文件时,如何在头文件中排除C++特定的代码?我想使用编译器宏,如:
// SomeClass.h - a file I want to import in C++ and Objectice-C classes
#if CPLUSPLUS
#import "CPlusPlusLibrary.h"
#endif
@interface SomeClass : BaseClass
{
#if CPLUSPLUS
CPlusPlusClass* variable;
#endif
}
@end
Run Code Online (Sandbox Code Playgroud) 嘿家伙我有一个C++类,我最近从*.cpp重命名为*.mm以支持objective-c.所以我可以添加以下Objective-c代码.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(notificationHandler:)
name:@"notify"
object:nil];
Run Code Online (Sandbox Code Playgroud)
我正在编写一个Objective-C++类接口,它必须可以从Objective-C和Objective-C++中使用.问题是,因为它必须可以从Objective-C中使用,所以我不能简单地使用C++类型.我想用指针做它,我想出了这个:
@interface SXDiff : NSObject {
@private
#ifdef __cplusplus
dtl::Diff<std::string, std::vector<std::string> > *_diff;
#else
void *_diff;
#endif
}
...
@end
Run Code Online (Sandbox Code Playgroud)
这样做会出现任何问题吗?有没有更好的方法呢?
请注意,使用指针只是为了使Objective-C和Objective-C++中的ivar大小相同.ivar只能在SXDiff(它的@private)类实现中使用.该实现是用Objective-C++编写的.
我发现分配块的行为与Objective-C类参数和C++类参数的行为不同.
想象一下,我有这个简单的Objective-C类层次结构:
@interface Fruit : NSObject
@end
@interface Apple : Fruit
@end
Run Code Online (Sandbox Code Playgroud)
然后我可以写这样的东西:
Fruit *(^getFruit)();
Apple *(^getApple)();
getFruit = getApple;
Run Code Online (Sandbox Code Playgroud)
这意味着,对于Objective-C类,块在它们的返回类型中是协变的:返回更具体的东西的块可以被视为块的"子类",返回更通用的东西.在这里,getApple传送苹果的getFruit块可以安全地分配给块.事实上,如果以后使用,它总是可以保存,以便Apple *在您预期时获得Fruit *.并且,从逻辑上讲,反过来不起作用:getApple = getFruit;不编译,因为当我们真的想要一个苹果时,我们不高兴得到一个水果.
同样,我可以这样写:
void (^eatFruit)(Fruit *);
void (^eatApple)(Apple *);
eatApple = eatFruit;
Run Code Online (Sandbox Code Playgroud)
这表明块在其参数类型中是协变的:可以使用可以处理更通用的参数的块,其中需要处理更具体的参数的块.如果一个街区知道如何吃水果,它也会知道怎么吃苹果.同样,反之亦然,这不会编译:eatFruit = eatApple;.
在Objective-C中,这一切都很好.现在让我们尝试使用C++或Objective-C++,假设我们有类似的C++类:
class FruitCpp {};
class AppleCpp : public FruitCpp {};
class OrangeCpp : public FruitCpp {};
Run Code Online (Sandbox Code Playgroud)
遗憾的是,这些块分配不再编译:
FruitCpp *(^getFruitCpp)();
AppleCpp …Run Code Online (Sandbox Code Playgroud)