Objective-C中的作用域详解

大华/华睿工业相机(摄像头)链接电脑,并用OpenCV打开 睿科是大华旗下机器视觉子公司,现在工业相机一般是华睿在产,要下载驱动程序,要到华睿官网哪里下载。由于我的电脑没有摄像头,所以摄像头序列化为0,电脑的第一个摄像头默认为0,序列号是0,1,2,3……,你是什么接口连接的就选择什么, 建议直接全选。我这里选择第二个,下载后点击安装,的你要点击识别右侧设置,设置。这个过程很简单,故不赘述。打开你的设备会在右边显示。 阅读详情

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

在此就转一篇基础的文章,由于讲的比较详细,我就稍做整理,标注下重点,然后写点自己的理解(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方法。然而,在这个程序中并不需要这么做。
【系统分析师】第1章-基础知识:绪论(核心总结) 《系统分析师教程(第二版)绪论》概述了系统分析师的核心角色与知识体系。作为信息系统开发的核心复合型人才,系统分析师需具备技术、业务、管理及道德等多维能力,贯穿需求分析、系统设计、协调沟通和质量保障全流程。知识体系涵盖系统工程方法论(如霍尔三维结构)、信息技术基础(数据库/网络技术)及管理学数学基础。教程梳理了该职业从数据处理专家到现代技术整合者的演变历程,并指出职业发展路径(初级分析师至CTO)。第二版新增大数据/AI等前沿内容,强化案例与实践,是软考官方权威教材,为读者构建系统化的学习框架。 阅读详情

相关推荐

MATLAB并行开不了的解决办法

在服务器上新安装了MATLAB 2013b,在开并行计算的时候出现了下列问题 经过在网上搜多这个问题,我感觉这个问题应该是安装的时候的验证问题或者激活不成功之类的。注意其中有一句validate the profile ‘local’ in the Cluster Profile Manager.在matlab官网上找到了设置Cluster Manager的教程,如下 parallel>

sinat_36713319的博客 5987

Objective-c 静态变量的定义

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

刘宇(LY)个人笔记 1058

手把手教你用微信小程序实现智能硬件音视频通话(含Linux/RTOS适配)

本文详细介绍了如何利用微信小程序硬件框架(WMPF)和音视频SDK,在智能硬件(包括Linux与RTOS设备)上实现音视频通话功能。文章从架构设计、设备端SDK集成、小程序VOIP插件开发到跨平台调试与性能优化,提供了全链路实战指南,帮助开发者打通微信小程序与嵌入式设备间的实时音视频通信。

ooo22的博客 329

Objective-C中的static用法

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

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

S7-1200PLC 与温控仪表Modbus RTU通信

硬件:cpu 1214C 目的:通过Modbus RTU协议,实现对温控仪表的控制 软件:Portal V14SP1

weixin_43922025的博客 3万+

【VSCode】【Clangd】从零构建:基于LLVM/Clangd+MINGW+CMake的Windows高性能C/C++开发环境实战

本文详细介绍了如何在Windows平台搭建基于LLVM/Clangd+MINGW+CMake的高性能C/C++开发环境。通过VSCode配置Clangd语言服务器,结合MINGW提供的GCC工具链和CMake的跨平台构建能力,实现轻量级、高效率的开发体验。文章包含从环境准备到实战配置的完整指南,特别适合追求开发效率和跨平台兼容性的开发者。

weixin_28839629的博客 312

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

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

Miss Yasiky 的专栏 2336

zabbix系列:内存VM.MEMORY.SIZE监控之total、free、pused、available 参数说明

free -m buffer是即将要被写入磁盘的,而cache是被从磁盘中读出来的. zabbix Web total:1046/1024=1.02G Available:216/1046=20.65% zabbix参数 total- 总物理内存. free- 可用内存. active- 内存当前使用或最近使用,所以它在RAM中。 inactive- 未使用内存. wired- 被标记为始终驻留在RAM中的内...

NIO4444 5667

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

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

qq_37778064的博客 1105

华为OD机考 新系统真题 【区分奇偶的数组排序】

华为OD机试 新系统真题【区分奇偶的数组排序】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【区分奇偶的数组排序】多语言题解。

qq_45776114的博客 511

YOLO26中的PPM空间金字塔池化:改良设计与多尺度特征提取教程

在计算机视觉的语义分割任务中,准确理解图像中的上下文信息至关重要。例如,在街景图像中,可能同时存在远处的小汽车和近处的大建筑物,网络需要具备捕获多尺度上下文信息的能力。例如,要正确识别图像中的"船",不仅需要看到船本身的特征,还需要理解周围的水面环境。金字塔的每一层对应不同的池化尺度,从细粒度到粗粒度,形成了多层次的特征表示。PPM(Pyramid Pooling Module)正是为了解决这一问题而提出的模块,它通过构建金字塔形状的池化结构,有效地聚合不同尺度的上下文信息,从而提升语义分割的精度。

LXY_LOVE36的博客 82

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

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

weixin_34049032的博客 275

Vue - 超强实现网页禁止浏览器缩放功能,浏览器缩放时保持网页不变形、元素不会被挤压等,屏蔽浏览器鼠标滚轮缩放页面(提供详细示例代码,一次引入整个网站无人可以搞乱你的页面布局及样式)

vue,nuxt,禁止浏览器缩放,如何用户缩放浏览器导致页面变形,网页缩放后页面变形了怎么办,怎么解决网站被缩放后元素乱套错乱,vue怎么禁止网页不被缩放,vue如何禁止浏览器缩放,vue缩放网页变形影响布局怎么办,vue电脑分辨率及缩放导致页面变形的问题,前端页面解决浏览器或者系统被放大和缩小导致的显示问题,Vue中页面自适应缩放,如何防止Vue页面缩放时变形/调整大小,Vue项目中,防止页面被缩放和放大,vue等比例缩放网页,网页缩放后界面变形咋办,禁止页面缩放,vue禁止浏览器改变窗口大小,Vue项目

🏆 前端领域优质创作者 1万+

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

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

code life 3568

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

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

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

陈鹏 2228

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Objective-C成员变量的作用域

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

麦子专栏 659

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

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、付费专栏及课程。

余额充值