Objective-C中的作用域详解

Anylabeling与SAM协同:从智能标注到YOLO数据集构建的完整实践 本文详细介绍了Anylabeling与SAM协同标注的完整实践,从智能标注到YOLO数据集构建的全流程。通过结合SAM的自动分割能力和Anylabeling的交互式标注,显著提升标注效率,特别适合小样本、复杂形状和多类别标注场景。文章还提供了环境搭建、标注优化技巧以及YOLO格式转换的实用指南。 阅读详情

我君哥说过“基础的知识再讨论也不为过”,想必很多人都深有体会。

在此就转一篇基础的文章,由于讲的比较详细,我就稍做整理,标注下重点,然后写点自己的理解(pending)。

原文地址:http://www.itivy.com/iphone/archive/2011/12/21/iphone-objective-c-scope.html


在Objective-C中,可以使用几种方式影响程序中变量的作用域。可以改变实例变量以及定义在函数外部或内部的普通变量的作用域。在下面的讨论中,我们使用术语模块(module)来引用包含在一个源文件中任何数目的方法或者函数定义。

控制实例变量作用域的指令

目前,你知道在Objective-C中,实例变量的作用域只限于为该类定义的实例方法。因此,任何实例方法都能直接通过变量名来访问该类的实例变量,而无需特别的操作。

你还知道,Objective-C的实例变量可通过子类进行继承。继承类的实例变量同样可以通过变量名在该子类定义的方法中直接访问。同样,这也无需执行其他特别的操作。

在接口部分声明实例变量时,可以把以下三个指令放在实例变量之前,以便更精确地控制其作用域,它们是:

@protected — 这个指令后面的实例变量可被该类及任何子类中定义的方法直接访问。这是默认的情况。

@private — 这个指令后面的实例变量可被定义在该类的方法直接访问,但是不能被子类中定义的方法直接访问。

@public — 这个指令后面的实例变量可被该类中定义的方法直接访问,也可被其他类或模块中定义的方法直接访问。

@package — 对于64位图像,可以在实现该类的图像的任何地方访问这个实例变量。

如果要定义一个名为Printer的类,它包含两个私有实例变量pageCount和tonerLevel,并且只有Printer类中的方法才能直接访问它们,那么可以如下使用接口部分:

1
2
3
4
5
6
7
8
9
10
@interface Printer: NSObject
{
@ private
int pageCount;
int tonerLevel;
@ protected
// other instance variables
}
...
@end
由于这两个实例变量均为私有的,所以任何从Printer派生子类的人都无法访问它们。

这些特殊的指令和“开关”一样,所有出现在这些指令之后的变量(直到标志着变量的声明结束的右花括号为止)都有指定作用域,除非使用另一个指令。在前面的例子中,@protected指令确保它后面和}符号之前的实例变量可以被Printer的类方法访问,也可以被子类访问。

@public指令使得其他方法或函数可以通过使用指针运算符(一>)访问实例变量。将实例变量声明为公共的并不是良好的编程习惯,因为这违背了数据封装的思想(即,类隐藏它的实例变量)。

外部变量

如果在Objective-C程序的开始处(所有方法、类定义和函数定义之外)编写以下语句:

int gMoveNumber = 0;

那么这个模块中的任何位置都可以引用这个变量的值。在这种情况下,我们说gMoveNumber被定义为全局变量。为了向阅读程序的人说明变量的作用域,按照惯例,用小写的g作为全局变量的首字母。

实际上,在Objective-C中,这样的定义使得其他文件也可以访问变量gMoveNumber的值。确切地说,前面语句不仅将gMoveNumber定义为全局变量,而且将其定义为外部全局变量。

外部变量是可被其他任何方法或函数访问和更改其值的变量。在需要访问外部变量的模块中,变量声明和普通方式一样,只是需要在声明前加上关键字extern。这就告知系统,要访问其他文件中定义的全局变量。下面这个例子说明如何将gMoveNumber声明为外部变量:

extern int gMoveNumber;

现在,包含前面这个声明的模块就可以访问和改变gMoveNumber的值。同样,通过在文件中使用类似的extern声明,其他模块也可以访问gMoveNumber的值。

使用外部变量时,必须遵循下面这条重要原则:变量必须定义在源文件中的某个位置。这是通过在所有方法和函数外部声明变量,并且前面不加关键字extern,如下所示:

int gMoveNumber;

这里,前面显示过,可以为这个变量指派初始值。

定义外部变量的第二种方式是在所有函数之外声明变量,在声明前面加上关键字extern,同时显式地为变量指派初始值,如下所示:

extern int gMoveNumber = 0;

然而,这并不是首选的方法。编译器将给出警告消息:提示你已将变量声明为extern的,并同时为变量赋值。这是因为使用关键字extern的表明这条语句是变量的声明而不是定义。记住,声明不会引起分配变量的存储空间,而定义会引起变量存储空间的分配。因此,前面的例子强行将声明当作定义处理(通过指派初始值),所以违背了这个规则。

处理外部变量时,变量可以在许多地方声明为extern,但是只能定义一次。

通过观察一个小程序例子来说明外部变量的用法。假设我们定义了一个名为Foo的类,并将以下代码键入一个名为main.m的文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
#import “Foo.h”
int gGlobalVar = 5;
int main ( int argc, char *argc[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Foo *myFoo = [[Foo alloc] init];
NSLog (@”%i “, gGlobalVar);
[myFoo setgGlobalVar: 100]
NSLog (@”%i”, gGlobalVar);
[myFoo release];
[pool drain];
return 0;
}
在前面的程序中,gGlobalVar定义为全局变量,因此任何方法〔或函数)只要正确地使用extern声明,都可以访问它。假设Foo方法setgGlobalVar:如下所示:

1
2
3
4
5
-( void ) setgGlobalVar: ( int ) val
{
extern int gGlobalVar;
gGlobalVar = val;
}
该程序将在终端生成以下结果:

1
2
5
100
这就证明了方法setgGlobalVar:可以访问和改变外部变量gGlobalVar的值。

如果有很多方法需要访问gGlobalVar的值,只在文件的开始进行一次extern声明将比较简便。但是如果只有一个或少数几个方法要访问这个变量,就应该在其中每个方法中单独进行extern声明。这样将使程序的组织结构更清晰,并且使实际使用变量的不同函数单独使用这个变量。注意,如果变量定义在包含访问该变量的文件中。那么不需要单独的extern声明。

静态变量

前面所示的例子与数据封装原则以及良好的面向对象编程技术相违背。然而,可能需要下面这种变量:它们的值在经过不同的方法调用时是共享的。虽然在Foo类中将gGlobalVar定义为实例变量似乎也不太合理,但是,更好的方法可能是通过将访问限制在类中定义的setter和getter方法中,将实例变量“隐藏”在Foo类中。

现在,你知道在方法之外定义的变量不仅是全局变量而且是外部变量。然而,在很多情况下你想要将变量定义为全局变量但不是外部变量。换句话说,希望定义的全局变量只在特定模块(文件)中是全局的。这种变量在下面的情况中很有意义:除了特定类中的方法,再没有其他方法需要访问这个特定变量。要做到这一点,可以在包含这个特定类实现的文件中将该变量定义为static。

如果语句

static int gGlobalVar = 0;

声明在任何方法(或函数)之外,那么在该文件中,所有位于这条语句之后的方法或函数都可以访问gGlobalVar的值,而其他文件中的方法和函数则不行。

你会想起类方法不能访问实例变量(你可能考虑为什么又是这样)。然而,可能希望类的方法可以设定和访问一些变量。简单的例子是类的分配器方法,它要记录类已经分配空间的对象数目。实现这项任务的方式是在类的实现代码文件中设定静态变量。由于这个变量不是实例变量,所以分配器方法可以直接访问它。类的用户不用知道这个变量。因为它是定义在实现文件中的静态变量,作用域只是文件内部。因此,用户不能直接访问该变量,也就没有违背数据封装的概念。如果需要从类之外访问该变量,则可以编写一个方法来获取该变量的值。

下面的代码【1】对Fraction的类定义进行了扩充,增加了两个新方法。allocF类方法分配一个新的Fraction对象,同时记录分配了多少Fraction, count方法则返回这个数的值。注意,后者也是类方法。也可以作为实例方法实现,然而,与向类的特定实例发送消息相比,询问类已经分配了多少实例更有意义。

下面是在头文件Fraction.h中添加的这两个新的类方法声明:

1
2
+(Fraction *) allocF;
+( int ) count;
你可能注意到,继承来的alloc方法并没有被重载;相反,你定义了自己的分配器方法。这个方法就可以利用继承来的alloc方法。下面是需要在实现文件Fraction.m中加人的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@implementation Fraction
+(Fraction *) allocF
{
extern int gCounter;
++gCounter;
return [Fraction alloc];
}
+( int ) count
{
extern int gCounter;
return gCounter;
}
// other methods from Fraction class go here
...
@end
count声明为静态使得定义在执行文件中的方法可以访问它,但是该文件之外都不可以访问。a11ocF方法仅仅递增gCounter变量,然后使用alloc方法创建一个新的Fraction,并返回结果;gCounter方法只是返回计数器的值,这样就隔离了来自用户的直接访问。

回忆一下,因为gCounter变量定义在该文件中,因此不需要在这两个方法中使用extern声明。声明只是为了让阅读该方法的人明白:他访问的变量是定义在该方法之外。变量名加g前缀也是出于同样的目的。因此,大多数程序员一般不使用extern声明。

代码【1】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#import “Fraction.h”
int main ( int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *a, *b, *c;
NSLog (@”Fractions allocated: %i”, [Fraction count]);
a = [[Fraction allocF] init]
b = [[Fract on allocF] init]
c = [[Fraction allocF] init];
NSLog (@”Fractions allocated: %i”, [Fraction count]);
[a release];
[b release];
[c release];
[pool drain];
return 0;
}
结果输出:

1
2
Fractions allocated: 0
Fractions allocated: 3
程序开始运行时,gCounter的值会自动置为0(你应该还记得,如果要将类作为整体进行任何特殊初始化,例如,将其他静态变量的值设置为一些非零值,可以重载继承类的initialize方法)。使用a11ocF方法分配三个Fraction实例之后,count方法检索counter变量的值,它被正确地设置为3。如果要重置计数器或将其设为特定的值,可以在类中添加一个setter方法。然而,在这个程序中并不需要这么做。
汉书HE8,好用的汇编代码编写工具 汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大 立即下载

相关推荐

计算机网络实验——入侵检测系统实验

在图1所示的网络结构中,此方案的具体实施:在路由器Router1的接口1出方向配置入侵检测策略,在收到ICMP ECHO请求包时,丢弃并同步向日志服务器报告警告,此时,终端PC2和PC3无法对终端PC0和PC1执行ping操作,并且日志服务器将记录相应的警告信息;在实验一的基础上,添加扩展分组过滤器,指定需要进行检测的信息流的类别,将扩展分组和对应的入侵检测规则进行绑定,使得只对特定的信息流进行入侵检测。加载指定类别的特征库,这里的指定类别是 ios_ips 类别中的 basic 子类别。

放放的博客 1563

Objective-c 静态变量的定义

编程中定义一个全局可用的值是很常见的,比如我们要保存登录操作的接口地址、加密时的密钥等等。 这些东西当然也可以保存到数据库等地方。但总有各种各样的缺点。 保存到一个工具类的静态变量中有很多优点,比如使用方便、修改方便。我们可以直接通过调用该工具类的静态获取值方法获取到值。要修改一些值时,因为都保存在这个地方,很容易就能找到他,并且只需要修改一次。 说了那么多,OC到底是怎么定义静态变量的呢

刘宇(LY)个人笔记 1058

VTK四视图联动避坑指南:解决vtkImagePlaneWidget窗宽窗位同步与切片序号更新的那些坑

本文详细解析了VTK四视图联动开发中的关键技术点与常见问题,包括切片位置同步、窗宽窗位同步的实现原理及回调机制设计。针对开发中遇到的回调事件不触发、渲染性能低下等问题,提供了实用的解决方案和优化技巧,帮助开发者高效构建医学影像和科学可视化应用。

weixin_42638178的博客 391

Objective-C中的static用法

Objective-C中的static变量表示的是类变量,仅初始化并存储一次,该类的所有实例共享该变量。 一般都定义在.m文件中,函数体之中或函数体之外。定义在函数体之中的static变量(局部静态变量),其作用域就是所在的函数体,即仅在所在函数体内可用。定义在函数体之外的static变量(全局静态变量),可以被所在类的所有方法访问。但是这两种方式定义的static变量都不可被其他类直接访问。

好脑瓜不如烂笔头,每天积累一点! 891

VSCode玩转STM32:手把手教你配置EIDE插件与OpenOCD调试(附野火DAP配置文件详解)

本文详细介绍了如何在VSCode中配置EIDE插件与OpenOCD进行STM32开发,特别针对野火DAP调试器提供了配置文件详解。从基础环境搭建到深度调试技巧,帮助开发者高效完成STM32项目开发,实现现代化嵌入式开发工作流。

weixin_26905487的博客 553

YOLOV8主干改进方法:C2f-Dual——DualConv轻量化双卷积设计(附改进代码)

DualConv是一种创新的卷积网络结构,旨在构建轻量级的深度神经网络。它通过结合3×3和1×1的卷积核处理相同的输入特征映射通道,优化了信息处理和特征提取。DualConv利用组卷积技术高效排列卷积滤波器,大大降低了计算成本和参数数量。

m0_74890428的博客 4700

objective-C:全局变量、静态变量、常量的区别

objective-C:全局变量、静态变量、常量的区别全局变量静态变量 全局变量 全局变量即该变量不仅可以在所定义的文件内被访问,也可以在其他文件中被访问。凡是定义在函数或方法之外的变量(除静态变量之外)都是全局变量。为了维护方便及可读性,全局变量一般定义在源文件(.m)的起始位置。其他文件想使用该全局变量时,需要先使用关键字extern进行声明。 全局变量,也叫外部全局变量,是整个工程唯一但,且...

Miss Yasiky 的专栏 2336

【自动驾驶端到端5:VADv2: End-to-End Vectorized Autonomous Driving via Probabilistic Planning】

从大规模人类驾驶演示中学习类人驾驶策略是有希望的。但是,规划的不确定性使得从驾驶演示中提取驾驶知识是有挑战性的。从统计学习的角度来看,动作(包括实际和速度)是高度随机的,受许多无法建模的潜在因素影响。

weixin_40000560的博客 1404

Object-C之静态变量与局部变量

OC程序设计之静态变量和局部变量 局部变量 在方法中声明的变量称之为局部变量; 其他的方法并不能直接访问这个变量,必须通过定义这个局部变量的方法来访问;该方法被调用时局部变量才被赋值;局部变量被存放在栈内,系统自动为其申请内存空间;局部变量没有默认的初始值,使用时必须给其赋值,而且在方法执行一次过后,静态变量的的值也随其消失,在第二次调用这个方法时,赋值语句会再执行一次。 有例有真相~下面我们...

qq_37778064的博客 1105

服务器取证——服务器基础知识

服务器基础知识

记录并分享学习安全的知识点.. 2481

26、遥感图像无监督变化检测方法解析

本文详细解析了遥感图像中的无监督变化检测方法,重点介绍了基于快速模糊 C-均值聚类的无监督变化检测方法(CDFFCM)在滑坡映射中的应用。CDFFCM 方法利用图像结构信息和高斯金字塔技术,提高了检测的准确性,减少了参数数量,并缩短了计算时间。该方法通过与传统方法的对比,展现出在高分辨率遥感图像滑坡检测中的显著优势。此外,文章还探讨了 CDFFCM 的未来发展趋势,包括技术融合、多模态数据应用以及智能化与自动化方向。

game4的博客 149

源码阅读:SDWebImage(六)——SDWebImageCoderHelper

该文章阅读的SDWebImage的版本为4.3.3。 这个类提供了四个方法,这四个方法可分为两类,一类是动图处理,一类是图像方向处理。 1.私有函数 先来看一下这个类里的两个函数 /** 这个函数是计算两个整数a和b的最大公约数 */ static NSUInteger gcd(NSUInteger a, NSUInteger b) { NSUInteger c; while ...

weixin_34049032的博客 275

Unity之Timeline教程

Unity Timeline是Unity的一种时间轴编辑器工具,用于制作和管理游戏中的动画、剧情以及事件触发。它提供了直观的界面,使得开发者可以通过拖放操作轻松创建和编辑时间轴。Activation Track:用于控制物体的激活状态。可以在轨道上添加关键帧,控制物体的激活和非激活状态。Animation Track:用于处理物体的动画。可以在此轨道上添加关键帧,编辑物体的动画状态。Audio Track:用于处理场景中的音频。可以管理音频的播放、暂停、淡入淡出等操作。

TxNet 9441

Objective-C中的作用域静态变量详解

和c++一样,objective c中静态变量使用static关键字进行定义。例如:static NSUInteger n; 需要注意的是该static变量的作用域,它的作用域是在定义该变量的.m文件范围内。         和c++不同,objective c不支持类静态成员变量(也就是不支持class variables),通常的做法是在class之外定义静态变量来代替。

code life 3568

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Objective-C语言--实例变量作用域修饰符

Objective-C实例变量作用域修饰符

陈鹏 2228

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Objective-C成员变量的作用域

OC的变量作用域,基本上和Java差不多, 默认这边是@protected。 Objective-C成员变量的作用域有四个关键字:@public,@private,@protected,@package,最后一个在开发过程中用到的较少。 @public:任何地方都可以直接访问成员变量,如main.m函数,任何一个类。 @private:仅仅在当前类的实现@implementation

麦子专栏 659

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

OC开发之——成员变量的作用域(25)

一 概述 局部变量,全局变量都有自己的作用域,成员变量也不例外,成员变量有一下四种类型 @private:只能在当前类的实现@implementation中直接访问 @protected:可以在当前类以及子类的实现@implementation中直接访问 @public:任何地方都可以直接访问 @package:同一个“体系内(框架)"可以访问,介于@private和@public之间 二 ...

我的博客 337

IOS基础---Objective-C学习之点语法和变量作用域

一、点语法 1. 认识点语法 声明一个Person类: #import @interface Person : NSObject { int _age;//默认为@protected } - (void)setAge:(int)age; - (int)age; @end   Person类的实现:  #import "Person

292

Objective-C 2.0 with Cocoa Foundation--- 7,对象的初始化以及实例变量的作用域

7,对象的初始化以及实例变量的作用域 本系列讲座有着很强的前后相关性,如果你是第一次阅读本篇文章,为了更好的理解本章内容,笔者建议你最好从本系列讲座的第1章开始阅读,请点击这里。  到目前为止,我们都使用的是下列方式创建对象 [类名 new];

lego2816的专栏 450

Objective-C 关键字 学好必知

a. 关于变量的作用域; b.静态变量(static); c.atomic和nonatomic ; 关于变量的作用域; protected—Methodsdefinedintheclassandanysubclassescandirectlyaccesstheinstancevariablesthatfollow.This...

weixin_30311605的博客 61

Objective-C小白入门:什么是Objective-C

Objective-C 咳咳,今天我是你的私教美少女朵朵,开始上课。 接触一门新语言,先要了解它的历史。 Objective-C 是一种简单的计算机语言,设计为可以支持真正的面向对象编程。Objective-C 通过提供类定义,方法以及属性的语法,还有其他可以提高类的动态扩展能力的结构等,扩展了标准的 ANSI C 语言。类的语法和设计主要是基于 Smalltalk,最早的面向对象编程语言之一。 如果你以前使用过其他面向对象编程语言,那么下面的信息可以帮助你学习 Objective-C ...

程序媛乐园 5248

Objective-C代码块Block详解

block代码块是OC的一个特性,除了可执行的代码外,还可能包含变量的自动绑定(栈),或内存托管(堆)。所以一个block维护一个状态集(数据),可以在任何时候执行。block用来作为回调特别有用。     block可以作为函数参数或者函数的返回值,而本身又可以带输入参数或返回值。在多线程,异步任务,集合遍历,接口回调等地方用得比较多。使用标识符^.。为了性能,block都是分配在栈stack

乞力马扎罗的雪CYF的博客 3889

Objective-C中Block详解

Block 是 Objective-C 语言的一种特性,它允许你定义一段可重用的代码,并在你的代码中像变量一样使用这段代码。Block 可以捕获和存储它所在的环境中的变量和常量。Block 是一种可执行的代码块,可以看作是带有自动捕获变量能力的匿名函数。在这个示例中,是一个 Block,它没有参数也没有返回值,当被调用时,它会打印一条消息。

Gamin 2335

Objective-C 中的NSValue的详解

Objective-C 中的NSValue的详解 (2013-01-28 19:16:57)转载▼ 分类: Objective-C 一个NSValue对象是用来存储一个C或者Objective-C数据的简单容器。它可以保存任意类型的数据,比如int,float,char,当然也可以是指pointers, structures, and object ids。NSValue类的目标就是允许以上数据

lucifer_app3的博客 665
上一篇: 从数组到类簇的学习总结
下一篇: 查找 EXC_BAD_ACCESS 问题根源的方法
xml_eason
博客等级 码龄14年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值