标签: objective-c++

将 Objective-C 块存储在 std::function 中是否安全?

我想将回调块从 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。

objective-c++ clang++

5
推荐指数
1
解决办法
595
查看次数

Swift 包管理器:将编译标志添加到单个文件 -fno-objc-arc

概述

我正在将 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

5
推荐指数
1
解决办法
3091
查看次数

Metal GPU 帧时间表现不直观

我在自己的应用程序中遇到了一个有趣的 Metal 性能问题,我只需对此示例项目进行少量调整即可重现该问题。我的视图大小约为 1600x900,如下所示:

\n

在此输入图像描述

\n

每帧有两次绘制调用,一次用于背景,一次用于线条。背景由4个顶点组成,线条大约有2000个顶点。当场景像上面一样绘制时,Xcode 的 GPU 帧捕获告诉我整个帧需要大约 4 毫秒(!)。一些观察结果:

\n
    \n
  • 当先画线时,该帧只需要~30 \xc2\xb5s
  • \n
  • 当仅绘制四个顶点(构成背景)时,框架需要 ~3 \xc2\xb5s
  • \n
  • 仅绘制线条时,帧需要约 40 \xc2\xb5s
  • \n
  • 当像上面一样绘制时,但只有线的前 ~900 个顶点,整个框架需要 ~4 \xc2\xb5s
  • \n
\n

这对我来说没有意义。为什么上述变化会对帧时间产生如此巨大的影响?这是 100 倍的差异。

\n

我正在 2018 Mac mini(配备 Intel UHD Graphics 630 1536 MB)上运行代码,以防万一这很重要。

\n
\n

以下是对演示项目所做的更改:

\n
    \n
  1. MTLBuffer在初始化期间创建两个s
  2. \n
\n
AAPLVertex quadVertices[] = { ... 4 vertices omitted ... };\nquadBuffer = [_device newBufferWithBytes:quadVertices length:4 * sizeof(AAPLVertex) MTLResourceStorageModeManaged];\n\nAAPLVertex dataVertices[] = { ... ~2000 vertices …
Run Code Online (Sandbox Code Playgroud)

macos gpu intel objective-c++ metal

5
推荐指数
1
解决办法
478
查看次数

Objective-C与Objective-C 2.0之间的差异

我保留了同一天出版的2本图书馆书籍.我在架子上看到它们,并意识到它们是相同的,除了一个是关于ObjC,一个是关于ObjC 2.0.

另外,什么是Objective-C++?

objective-c objective-c++

4
推荐指数
1
解决办法
3233
查看次数

C++引用类型作为Objective-C++中的实例变量

在Objective-C++中禁止将C++引用类型作为实例变量.我该如何解决这个问题?

c++ objective-c objective-c++

4
推荐指数
1
解决办法
2247
查看次数

什么是C++中最基本的类

我希望这个问题不是太傻,但标准C++中最基本的类是什么?宾语?宾语?

class MyObject : public object{  ...
Run Code Online (Sandbox Code Playgroud)

我得到"令牌之前的预期类名"

是否有显示标准c ++类继承的地图,图表或图像? 这样的东西,但对于C++

c++ objective-c objective-c++

4
推荐指数
3
解决办法
440
查看次数

如何在Xcode中用宏检测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++ macros xcode objective-c objective-c++

4
推荐指数
2
解决办法
2973
查看次数

如何使用Objective-C++在C++类中向NSNotificationCenter添加观察者?

嘿家伙我有一个C++类,我最近从*.cpp重命名为*.mm以支持objective-c.所以我可以添加以下Objective-c代码.

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(notificationHandler:) 
                                                 name:@"notify"
                                               object:nil];
Run Code Online (Sandbox Code Playgroud)
  • 如何/我可以在c ++中编写notificationHandler方法吗?
  • 设置addObserver:self属性是否有效?

iphone objective-c++ nsnotificationcenter

4
推荐指数
2
解决办法
4985
查看次数

在Objective-C代码中使用Objective-C++类和C++实例变量

我正在编写一个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++编写的.

c++ objective-c objective-c++

4
推荐指数
1
解决办法
1287
查看次数

分配块指针:Objective-C与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)

pointers subclass clang objective-c++ objective-c-blocks

4
推荐指数
1
解决办法
900
查看次数