百度APP iOS端包体积50M优化实践(三) 资源优化

发表于 1年以前  | 总阅读数:1086 次

一. 前言

百度APP iOS端包体积优化系列文章的前两篇重点介绍了包体积优化整体方案、各项优化收益和图片优化方案,图片优化是从无用图片、Asset Catalog和HEIC格式三个角度做深度优化。本文重点介绍资源优化,在百度APP实践中,资源优化包括大资源优化、无用配置文件和重复资源优化。不管是资源优化还是代码优化,都需要分析Mach-O文件,以获取资源和代码的引用关系,本文先详细介绍Mach-O文件。

百度APP iOS端包体积优化实践系列文章回顾:

《百度APP iOS端包体积50M优化实践(一)总览》:https://mp.weixin.qq.com/s/ANbFzg7X932o-iDpa8FcxQ

《百度APP iOS端包体积50M优化实践(二) 图片优化》:https://mp.weixin.qq.com/s/RR7sjhkuTFgUp7S5E8ECMw

二. Mach-O文件详解

2.1 简介

Mach-O为Mach Object文件格式的缩写,用于记录可执行文件、目标代码、动态库和内存转储的文件格式,是运用于Mac以及iOS系统上。

2.2 分析Mach-O文件的工具

2.2.1 MachOView分析

  • MachOView下载地址: http://sourceforge.net/projects/machoview/
  • MachOView源码地址:https://github.com/gdbinit/MachOView

用MachOView能查看MachO文件信息,启动MachOView,在状态栏中点击file,打开MachO文件,如下图所示。

2.2.2 otool命令查看

mac自带otool工具,otool -arch arm64 -ov xxx.app/xxx,可获取所有项目的类结构及定义的方法,示例代码如下所示:

Contents of (__DATA,__objc_classlist) section
0000000100008238 0x100009980
    isa        0x1000099a8
    superclass 0x0 _OBJC_CLASS_$_UIViewController
    cache      0x0 __objc_empty_cache
    vtable     0x0
    data       0x1000083e8
        flags          0x90
        instanceStart  8
        instanceSize   8
        reserved       0x0
        ivarLayout     0x0
        name           0x100007349 ViewController
        baseMethods    0x1000082d8
            entsize 24
            count   11
            name    0x100006424 test4
            types   0x1000073e4 v16@0:8
            imp     0x100004c58
            name    0x1000063b4 viewDidLoad
            *****

下面列举otool常见命令:

命令 功能
otool -f xxx.app/xxx 查看fat headers信息
otool -a xxx.app/xxx 查看archive header信息
otool -h xxx.app/xxx 查看Mach-O头结构
otool -l xxx.app/xxx 查看load commands
otool -L xxx.app/xxx 查看依赖的动态库,包括动态库名称、当前版本号、兼容版本号
otool -t -v xxx.app/xxx 查看text section
otool -d xxx.app/xxx 查看data section
otool -o xxx.app/xxx 查看Objective-C segment
otool -I xxx.app/xxx 查看symbol table
otool -v -s TEXT cstring 获取所有静态字符串
otool -v -s TEXT objc_methname xxx.app/xxx 获取所有方法名称

2.3 查看文件格式

采用file命令可以查看文件格式,lipo -info可查看该Mach-O文件支持的具体CPU架构。

~ % file /Users/ycx/Desktop/demo.app/demo
/Users/ycx/Desktop/demo.app/demo: Mach-O 64-bit executable arm64
~ % lipo -info /Users/ycx/Desktop/demo.app/demo
Non-fat file: /Users/ycx/Desktop/demo.app/demo is architecture: arm64

2.4 文件结构

2.4.1 总体结构

Mach-O文件主要由三部分组成Header、LoadCommands、Data,在MachO文件的末尾,还有Loader Info信息,表示可执行文件依赖的字符串表,符号表等信息。

2.4.2 Header(头部)

2.4.2.1 数据结构

Header(头部): 用于描述当前Mach-O文件的基本信息(CPU类型、文件类型等),XNU代码路径:EXTERNAL_HEADERS/mach-o/loader.h,数据结构如下所示:

struct mach_header_64 {
  uint32_t  magic;    /* mach magic number identifier */
  cpu_type_t  cputype;  /* cpu specifier */
  cpu_subtype_t  cpusubtype;  /* machine specifier */
  uint32_t  filetype;  /* type of file */
  uint32_t  ncmds;    /* number of load commands */
  uint32_t  sizeofcmds;  /* the size of all the load commands */
  uint32_t  flags;    /* flags */
  uint32_t  reserved;  /* reserved */
};

2.4.2.2 查看字段值

命令otool -hv可查看Header每个字段值。

% otool -hv demo
demo:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64    ARM64        ALL  0x00     EXECUTE    22       3040   NOUNDEFS DYLDLINK TWOLEVEL PIE

用MachOView查看Header数据值:

2.4.2.3 字段具体含义

各个字段具体含义如下所示:

字段 说明
magic 魔数头,系统加载器通过该字段快速判断文件类型。armv7:FEEDFACE; arm64:FEEDFACF
cputype CPU类型
cpusubtype CPU指定子类型,inter、arm、powerpc等
filetype 说明文件类型(可执行文件、库文件、核心转储文件、内核扩展文件、DYSM文件、动态库等);MH_OBJECT 编译过程中产生的 obj文件;MH_EXECUTE 可执行二进制文件 ;MH_CORE CoreDump;MH_DYLIB 动态库;MH_DYLINKER 连接器linkerMH_KEXT_BUNDLE 内核扩展文件
ncmds 加载命令的条数
sizeofcmds 加载命令长度
flags dyld加载时的标志位;MH-NOUNDEFS表示:目标没有未定义的符号,不存在链接依赖;MH-DYLDLINK表示:该目标文件是dyld的输入文件;MH-TWOLEVEL表示:动态加载二级名称空间;MH-PIE表示:地址空间布局随机化

2.4.3 LoadCommands(加载命令)

2.4.3.1 数据结构

LoadCommands(加载命令): 用于描述文件的组织架构和在虚拟内存中的布局方式,告诉操作系统如何加载Mach-O文件中的数据。XNU代码路径:EXTERNAL_HEADERS/mach-o/loader.h,数据结构如下所示,其中cmd代表加载命令类型,cmdsize代表加载命令大小,在load_command数据结构后面加一个特定结构体信息,不同的cmd类型,结构体也不同。

struct load_command {
  uint32_t cmd;    /* type of load command */
  uint32_t cmdsize;  /* total size of command in bytes */
};
/* Constants for the cmd field of all load commands, the type */
#define  LC_SEGMENT  0x1  /* segment of this file to be mapped */
#define  LC_SYMTAB  0x2  /* link-edit stab symbol table info */
#define  LC_SYMSEG  0x3  /* link-edit gdb symbol table info (obsolete) */
#define  LC_THREAD  0x4  /* thread */
#define  LC_UNIXTHREAD  0x5  /* unix thread (includes a stack) */
#define  LC_LOADFVMLIB  0x6  /* load a specified fixed VM shared library */
#define  LC_IDFVMLIB  0x7  /* fixed VM shared library identification */
#define  LC_IDENT  0x8  /* object identification info (obsolete) */
#define LC_FVMFILE  0x9  /* fixed VM file inclusion (internal use) */
#define LC_PREPAGE      0xa     /* prepage command (internal use) */
#define  LC_DYSYMTAB  0xb  /* dynamic link-edit symbol table info */
#define  LC_LOAD_DYLIB  0xc  /* load a dynamically linked shared library */
#define  LC_ID_DYLIB  0xd  /* dynamically linked shared lib ident */
#define LC_LOAD_DYLINKER 0xe  /* load a dynamic linker */
#define LC_ID_DYLINKER  0xf  /* dynamic linker identification */
#define  LC_PREBOUND_DYLIB 0x10  /* modules prebound for a dynamically */
*****

2.4.3.2 查看字段值

用otool -lv命令可以看到该字段全部信息,如左下图所示,此外,我们也可用MachOView工具可更直观地观察具体字段,如右下图所示。

2.4.3.3 cmd类型及其具体作用

类型 作用
LC_SEGMENT/LC_SEGMENT_64 将文件中的段映射到进程地址空问中
LC_DYLD_INFO_ONLY 动态库信息,根据该命令是真正动态库绑定,地址重定向重要的信息
LC_SYMTAB 符号表信息
LC DYSYMTAB 动态符号表信息
LC_LOAD_DYLINKER 加载动态链接器
LC_UUID 文件的唯一标识,crash解析中也会有,去匹配dysm文件和crash文件
LC_VERSION_MIN_IPHONEOS 二进制文件要求的最低操作系统版本 (iOS Deployment Target)
LC_MAIN 程序主线程的入口地址
LC_ENCRYPTION_INFO_64 加密信息,查看文件是否加密,如果已加密需要砸壳
LC_LOAD_DYLIB 加载的动态库,包括动态库地址和名称,当前版本号,兼容版本号
LC_FUNCTION_STARTS 函数起始地址表

| LC_CODE_SIGNATURE | 代码签名信息 |

常见的cmd类型及其具体作用如下面表格所示:类型**作用**LC_SEGMENT/LC_SEGMENT_64将文件中的段映射到进程地址空问中LC_DYLD_INFO_ONLY动态库信息,根据该命令是真正动态库绑定,地址重定向重要的信息LC_SYMTAB符号表信息LC DYSYMTAB动态符号表信息LC_LOAD_DYLINKER加载动态链接器LC_UUID文件的唯一标识,crash解析中也会有,去匹配dysm文件和crash文件LC_VERSION_MIN_IPHONEOS二进制文件要求的最低操作系统版本 (iOS Deployment Target)LC_MAIN程序主线程的入口地址LC_ENCRYPTION_INFO_64加密信息,查看文件是否加密,如果已加密需要砸壳LC_LOAD_DYLIB‍加载的动态库,包括动态库地址和名称,当前版本号,兼容版本号LC_FUNCTION_STARTS函数起始地址表LC_CODE_SIGNATURE‍‍代码签名信息

2.4.3.4 LC_SEGMENT_64

2.4.3.4.1 数据结构

在众多cmd命令中,我们需要重点关注的是LC_SEGMENT/LC_SEGMENT_64,LC_SEGMENT是32位,LC_SEGMENT_64是64位,目前主流机型是LC_SEGMENT_64。LC_SEGMENT_64作用是如何将Data中的各个Segment加载入内存中,而和我们APP相关的代码及数据,大部分位于各个Segment中。其数据结构名称是segment_command_64,XNU代码路径:EXTERNAL_HEADERS/mach-o/loader.h,源码如下所示:

struct segment_command_64 { /* for 64-bit architectures */
  uint32_t  cmd;    /* LC_SEGMENT_64 */
  uint32_t  cmdsize;  /* includes sizeof section_64 structs */
  char    segname[16];  /* segment name */
  uint64_t  vmaddr;    /* memory address of this segment */
  uint64_t  vmsize;    /* memory size of this segment */
  uint64_t  fileoff;  /* file offset of this segment */
  uint64_t  filesize;  /* amount to map from the file */
  vm_prot_t  maxprot;  /* maximum VM protection */
  vm_prot_t  initprot;  /* initial VM protection */
  uint32_t  nsects;    /* number of sections in segment */
  uint32_t  flags;    /* flags */
};
字段 含义
Segment Name Segment名称
VM Address 该段被加载后在进程地址空间中的虚拟地址
VM Size 段的虚拟内存大小
File Offset 该段在文件中的偏移
File Size 段在文件中的大小
maxprot 段页面所需要的最高内存保护(可读 可写 可执行)
initprot 段页面初始的内存保护
nsects 段中包含section的数量
flags 其他标志位

Mach-O文件有多个段(Segment),每个段有不同的功能,每个段又按不同功能划分为多个区(section),四个Segment为__PAGEZERO、__TEXT、_DATA和_LINKEDIT,下面详细介绍。

2.4.3.4.2 _PAGEZERO

__PAGEZERO Segment是空指针陷阱段,主要是用来捕捉NULL指针的引用,是Mach内核虚拟出来的,是Mach-O加载进内存之后附加的一块区域,maxprot和initprot值都为VM_PROT_NONE,表示它不可读,不可写,如果访问__PAGEZERO段,会引起程序崩溃。从上图可以发现,VM Size是4GB,但是真实的File Size大小是0,它只是一个逻辑上的段,在Data中,根本没有对应的内容,也没有占用任何硬盘空间。

2.4.3.4.3 _TEXT

__TEXT Segment对应的就是代码段,下图是一张示例截图,其有11个Section,该段对应的内容加载到内存的过程是:从File Offset开始加载大小为File Size的文件,从虚拟地址VM Address开始装填,大小也是VM Size,VM Size跟文件大小File Size是相同的,我们发现其File Offset为0,在Mach-O文件布局中,__TEXT类型的Segment前面有_PAGEZERO类型的Segment,但_PAGEZERO段的File Offse和File Size为0,所以__TEXT段的File Offset为0。

maxprot和initprot值都为VM_PROT_READ和VM_PROT_EXECUTE,代码段权限是只读和可执行,防止在内存中被修改。

2.4.3.4.4 _DATA

__DATA Segment对应的就是数据段,maxprot和initprot值都为VM_PROT_READ和VM_PROT_WRITE,数据段权限是可读和可写。

2.4.3.4.5 _LINKEDIT

__LINKEDIT Segment用于描述链接信息段,指向存放 link 操作必要的数据段。

2.4.4 Data(数据段)

Mach-O的Data部分,其实是真正存储APP二进制数据的地方,前面的header和load command,仅是提供文件的说明以及加载信息的功能。

Data(数据段): 主要是代码、数据,包含了Load commands中需要的各个段(Segment)的数据,每个Segment可以有多个Section,下面列举一些常见的 Section。在Data(数据段)中,大写的字符串(如__TEXT)代表的是Segment,小写的字符串(如__objc_methtype)代表的是Section。Section用途__TEXT.__text主程序代码

__TEXT.__cstringC 语言字符串__TEXT.__constconst 关键字修饰的常量__TEXT.__stubs用于 Stub 的占位代码,很多地方称之为桩代码。

__TEXT.__stubs_helper当 Stub 无法找到真正的符号地址后的最终指向__TEXT.__objc_methnameObjective-C 方法名称__TEXT.__objc_methtypeObjective-C 方法类型__TEXT.__objc_classnameObjective-C 类名称__DATA.__data初始化过的可变数据__DATA.__la_symbol_ptrlazy binding 的指针表,表中的指针一开始都指向 __stub_helper__DATA.nl_symbol_ptr非 lazy binding 的指针表,每个表项中的指针都指向一个在装载过程中,被动态链机器搜索完成的符号__DATA.__const没有初始化过的常量__DATA.__cfstring程序中使用的 Core Foundation 字符串(CFStringRefs)__DATA.__bssBSS,存放为初始化的全局变量,即常说的静态内存分配__DATA.__common没有初始化过的符号声明__DATA.__objc_classlistObjective-C 类列表__DATA.__objc_protolistObjective-C 所有的protocol__DATA.__objc_imginfoObjective-C 镜像信息__DATA.__objc_selfrefsObjective-C self 引用__DATA.__objc_protorefsObjective-C 原型引用__DATA.__objc_superrefsObjective-C 超类引用**三. 资源优化**

3.1 简介

作为一个航母级别的APP,百度APP技术栈丰富多样,市面上常见的技术框架都有使用,如Hybrid框架、小程序框架、React Native框架、KMM和端智能。此外,百度APP作为日活过亿的APP,为满足用户复杂多变的需求,具有的功能包罗万象,如搜索、Feed、短视频、直播、购物、小说、地图、网盘、美颜、人脸识别、AR库等,导致内置的大块资源(大于40K)就有26M,具有很大的优化空间,资源优化分为三个部分,分别是大资源优化、无用配置文件和重复资源优化,本章节接下来详细介绍各个模块的优化方案。

3.2 大资源优化

3.2.1 获取大资源

资源是指plist、js、css、json、端智能模型文件等,因这些文件和图片在优化方式差异很大,所以把两者区分开来。获取大资源主要途径是递归遍历ipa包的所有资源,体积大于指定阈值的文件就是我们要针对性优化的大资源,在百度APP优化实践中我们选取了40K作为阈值,参考脚本如下所示:

def findBigResources(path,threshold):
    pathDir = os.listdir(path)
    for allDir in pathDir:
        child = os.path.join('%s%s' % (path, allDir))
        if os.path.isfile(child):
            # 获取读到的文件的后缀
            end = os.path.splitext(child)[-1]
            # 过滤掉dylib系统库和asset.car
            if end != ".dylib" and end != ".car":
                temp = os.path.getsize(child)
                # 转换单位:B -> KB
                fileLen = temp / 1024
                if fileLen > threshold:
                    #print(end)
                    print(child + " length is " + str(fileLen));
        else:
            # 递归遍历子目录
            child = child + "/"
            findBigResources(child,threshold)

3.2.2 优化方法

  • 异步下载:只要APP首次启动时不需要加载该资源,或者即使首次启动需要加载但是使用频率不高,那么该资源就可以走异步下载;
  • 资源压缩:当APP首次启动需要加载且频率较高的情况下,可以对大块资源先进行压缩内置APP,启动阶段异步线程解压再使用;

3.3 无用的配置文件

3.3.1 获取配置文件

从ipa包中获取plist、json、txt、xib等配置文件,百度技术方案采用的是排除法,因为实践中发现配置文件格式千奇百怪,很多业务模块出于安全考虑自定义各种后缀文件,无法穷举,所以采用了排除法。针对图片资源我们有专门的优化方法,所以首先将png、webp、gif、jpg排除掉,JS&CSS资源是一般HTML加载的,在mach-o文件中TEXT字段静态字符串常量不会有体现,所以也需要排除掉,最后获取到的就是我们需要的配置文件,参考脚本如下所示:

def findProfileResources(path):
    pathDir = os.listdir(path)
    for allDir in pathDir:
        child = os.path.join('%s%s' % (path, allDir))
        if os.path.isfile(child):
            # 获取读到的文件的后缀
            end = os.path.splitext(child)[-1]
            if end != ".dylib" and end != ".car" and end != ".png" and end != ".webp" and end != ".gif" and end != ".js" and end != ".css":
                print(child + " 后缀 " + end)
        else:
            # 递归遍历子目录
            child = child + "/"
            findProfileResources(child)

3.3.2 mach-o文件获取静态字符串常量

我们加载配置文件的代码经过编译链接最后都会以字符串形式存储到mach-o文件中,具体是TEXT字段静态字符串常量__cstring中,用otool命令可以获取,参考脚本如下所示:

lines = os.popen('/usr/bin/otool -v -s __TEXT __cstring %s' % path).readlines()

3.3.3 获取无用配置文件

前面获取的集合做diff,获取无用配置文件,确认无误后删除以减少包体积。如果你的资源名是拼接使用的,就无法命中,所以删除资源一定要逐个确认。

3.3.4 JS&CSS无用文件排查

JS&CSS文件具有特殊性,OC代码可以引用,HTML文件也可以加载引用,图片也是这种情况,但是上面提到的mach-o文件中TEXT字段只能覆盖OC文件的引用方式,而HTML加载才是主流场景,为此针对这种case百度APP采用跟无用图片检测类似的解决方案。

3.4 重复资源优化

从iPA包中获取所有资源文件,通过MD5判断资源是否重复,参考脚本如下所示:

def get_file_library(path, file_dict):
    pathDir = os.listdir(path)
    for allDir in pathDir:
        child = os.path.join('%s/%s' % (path, allDir))
        if os.path.isfile(child):
            md5 = img_to_md5(child)
            # 将md5存入字典
            key = md5
            file_dict.setdefault(key, []).append(allDir)
            continue
        get_file_library(child, file_dict)

def img_to_md5(path):
    fd = open(path, 'rb')
    fmd5 = hashlib.md5(fd.read()).hexdigest()
    fd.close()
    return fmd5

四. 总结

资源优化是包体积优化的重头戏,优化的过程中影响面可控,所以落地收益比较容易,百度APP经过两个季度的优化落地12M的收益,基本解决存量资源的优化问题,同时建立资源使用规范和相应的检测流水线解决增量问题。

本文对Mach-O文件格式做了系统阐释,并且详细介绍了百度APP大资源优化、无用配置文件和重复资源优化方案,后续我们会针对其他优化详细介绍其原理与实现,敬请期待。

参考链接

[1]、Mach内核介绍:https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/Mach/Mach.html

[2]、《深入解析Mac OS X & iOS操作系统》

[3]、XNU源码:https://github.com/apple/darwin-xnu

[4]、Mach-O介绍:https://alexdremov.me/mystery-of-mach-o-object-file-builders/

[5]、初识Mach-O文件:https://www.jianshu.com/p/81928c705c88

本文由哈喽比特于1年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/FQWCX0wkK6ifHQ8RhmmPsg

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
快速配置 Sign In with Apple 5年以前  |  7675次阅读
使用 GPUImage 实现一个简单相机 5年以前  |  5971次阅读
APP适配iOS11 5年以前  |  5749次阅读
 目录