`
sarin
  • 浏览: 1756999 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
E3b14d1f-4cc5-37dd-b820-b6af951740bc
Spring数据库访问系列...
浏览量:173669
C2083dc5-6474-39e2-993e-263652d27795
Android学习笔记
浏览量:368140
5f40a095-b33c-3e8e-8891-606fcf3b8d27
iBatis开发详解
浏览量:189271
B272a31d-e7bd-3eff-8cc4-c0624ee75fee
Objective-C学习...
浏览量:99844
社区版块
存档分类
最新评论

Objective-C学习笔记12:高级数据类型一

阅读更多
    接上文
    之前介绍过变量和数据类型,那么我们来看看Objective-C中更深层次的变量和数据类型。比如我们要初始化一个分数类,可以使用如下代码:
Fraction *fraction = [[Fraction alloc] init];

    那么为了简便,我们已经将代码简化为:
Fraction *fraction = [[Fraction new];

    此时,若想对分数进行赋值,那么必须再写一个方法来完成,而new也是达不到这个效果的,很显然这里我们需要对分数类进行业务初始化,使得其创建好就具备数值,那么这个业务初始化方法可以这么来写:
#import <Foundation/Foundation.h>

@interface Fraction : NSObject

@property int numerator,denominator;

-(void) print;
-(double) convertToNum;
-(void) setTo:(int) n over: (int) d;
-(Fraction *)add:(Fraction *)f;
-(void) reduce;
-(Fraction *) initWith:(int) n over:(int) d;

@end

    首先在分数类的定义中加入initWith...over方法,然后编写实现代码:
-(Fraction *) initWith:(int)n over :(int)d
{
    self=[super init];
    if(self){
        [self setTo:n over:d];
    }
    return self;
}

    在实现中我们调用super的init方法实现对象初始化,之后使用self来进行业务初始化,那么主函数就必须使用alloc来创建空间了,因为我们这里不能再使用new来合并二者了,代码如下:
#import "Fraction.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Fraction *fractionA=[[Fraction alloc] initWith:1 over:3];
        Fraction *fractionB=[[Fraction alloc] initWith:2 over:5];
        
        Fraction *result=[fractionA add:fractionB];
        [result print];
    }
    return 0;
}

编译运行,我们可以得到如下效果:




    这里我们就是编写了业务初始化的方法,使用一行语句完成对象的创建和初始化,回过头来看看初始化方法,可以过滤出一个模板:
-(id) init
{
    self=[super init];
    if(self){
        //业务初始化代码
    }
    return self;
}

    那么为了使用这个初始化规则,我们进一步对分数类进行修改,提供一个可以作为父类方法的init方法,代码如下:
#import <Foundation/Foundation.h>

@interface Fraction : NSObject

@property int numerator,denominator;

-(void) print;
-(double) convertToNum;
-(void) setTo:(int) n over: (int) d;
-(Fraction *)add:(Fraction *)f;
-(void) reduce;
-(Fraction *) initWith:(int) n over:(int) d;
-(id) init;
@end

    我们覆盖Fraction类的init方法,提供如下实现:
-(id) init
{
    return [self initWith:1 over:1];
}

    我们人为将分数都初始化为1,那么主函数为:
#import "Fraction.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Fraction *fraction=[Fraction new];
        [fraction print];
    }
    return 0;
}

    编译运行,我们得到如下结果:




    其实这里的new还是合并调用了alloc和init,alloc还是NSObject中的方法,而init则是调用我们覆盖的方法,因此初始化的效果为1,这个很好理解。
    对于变量,有一个概念叫作用域,我们之前没有使用访问控制指令来修饰变量,那么Objective-C提供了以下几种访问控制指令,结合继承我们来看看。
    @private指令,该指令修饰的实例变量仅能在该类中访问,不能被子类访问。我们在实现部分定义的变量默认就是这种作用域。
    @protected指令,该指令修饰的实例变量可以被该类及其子类访问。那么我们在接口部分定义的变量默认就是这种作用域。
    @public指令,该指令修饰的实例变量不仅可以被该类访问,其他类也可以进行访问。
    那么如何来使用这些访问控制指令呢,可以使用如下的代码段:
@interface ClassA
{
	@private
		int n;
		int b;
	@protected
		int i;
		int j;
	//其它实例变量
}

    这种语法结构告诉我们跟在指令之后的变量都是该访问控制类型的,除非遇到下一个访问控制指令来修饰。如上面的代码n和b就是private类型的,而i和j是protected类型的。对于public类型的变量则不推荐使用,因为它会破坏数据封装的原则。
    我们来看一下全局变量这个概念。如果在某程序的开始处(所有函数,类定义之外)定义了一个变量,那么在这个模块的任何位置都引用这个变量的值,这个变量也叫做全局变量。
    关键字extern可以标识访问其它文件定义的全局变量。使用extern标识外部变量时要保证变量在所有的函数和类定义之外声明,并且不能加关键字。
    我们来看下面的示例代码:
#import <Foundation/Foundation.h>

@interface Foo : NSObject

-(void) setGlobalVar:(int)val;

@end

    一个简单的类定义,用于设置全局变量,那么其实现代码为:
#import "Foo.h"

@implementation Foo

-(void) setGlobalVar:(int)val
{
    extern int globalVar;
    globalVar=val;
}

@end

    使用extern关键字来标识一个外部的全局变量,注意变量命名要和外部的全局变量一致,那么主函数就必须这么来写:
#import "Foo.h"

int globalVar=10;

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Foo *foo=[Foo new];
        NSLog(@"%i",globalVar);
        
        [foo setGlobalVar:406];
        NSLog(@"%i",globalVar);
    }
    return 0;
}

    这里的全局变量globalVar和方法中使用extern修饰的变量名一致,才可以对其进行修改,那么编译运行后我们就得到如下结果:




    当然可以尝试不同命名所带来的错误,从而更好理解这个问题。
    下面一个概念是静态变量,全局变量和extern的使用破坏了数据封装原则和面向对象的思想,而有时需要在不同的方法中共享某值,则还需要使用它。上面的例子说明方法之外定义的变量不仅是全局变量而且还可以作为外部变量,那么更多情况是我们需要全局变量而不是外部变量。也就是希望某全局变量仅在特定文件中使用,那么要做到这一点就会使用到static关键字。加上了static关键字,那么外部的extern就不会起作用了。
    作为示例,我们继续修改分数类Fraction,比如说我们要记录到底创建了多少个分数对象,那么该如何来实现呢?看下面的代码:
+(Fraction *) allocF
+(int) countF

    在分数类定义中添加两个类方法,使用+号修饰,表明它们不是实例变量,一个用于申请空间,注意这里不要覆盖alloc方法,因为分配空间涉及物理层面的操作,尽量避开,之后的countF就是记录该类创建了几次,需要使用到全局变量,在实现代码中,首先定义全局变量:static int gCount;之后完善上面两个方法:
+(Fraction *) allocF
{
    gCount++;
    return [Fraction alloc];
}

+(int) countF
{
    return gCount;
}

    那么主函数中我们可以这么来写:
#import "Fraction.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Fraction *fractionA,*fractionB,*fractionC;
        
        NSLog(@"%i",[Fraction countF]);
        
        fractionA=[[Fraction allocF] init];
        fractionB=[[Fraction allocF] init];
        fractionC=[[Fraction allocF] init];
        
        NSLog(@"%i",[Fraction countF]);
    }
    return 0;
}

    编译运行(此时请删除之前的Foo类,因为我们已经去掉全局变量globalVar了,保留它们就会报错,因为方法中有extern修饰的变量定义),我们来看下结果:




    说明静态变量gCount保留了方法allocF的调用次数。这里的静态变量初始值为0,那么若要重置这个静态变量的值,可以提供setter方法来实现,而此例中并不需要这么做。
    接下文
  • 大小: 50.8 KB
  • 大小: 50 KB
  • 大小: 58.2 KB
  • 大小: 65.2 KB
3
2
分享到:
评论
4 楼 itfanr 2015-01-24  
learner576539763 写道
这是object-c2.0程序设计里的教材内容,你让作者咋更?

??
3 楼 zzwfsnh 2015-01-05  
非常不错呀,作为我入门的第一步,赞!
2 楼 learner576539763 2014-11-19  
这是object-c2.0程序设计里的教材内容,你让作者咋更?
1 楼 zwlfyl 2013-04-27  
不更新了?

相关推荐

    Objective-C 基础语法学习项目

    1. **Objective-C核心类型**:`NSString`、`NSArray`、`NSDictionary`是Objective-C中最常用的容器类型,分别用于存储字符串、数组和字典数据。 2. **协议**:通过定义协议可以规定类应实现的方法或属性,增强了程序...

    objective-c编程入门学习笔记

    Objective-C支持多种数据类型,并且提供了丰富的运算符。例如,可以进行简单的算术运算: ```objective-c int sum = 20 + 25; NSLog(@"The sum is %i", sum); ``` ##### 3. 键盘输入 Objective-C中的键盘输入可以...

    Objective-C&UIKit自学笔记

    Objective-C是一种面向对象的编程语言,它在C语言的基础上增加了SmallTalk-80的特性,主要应用于Apple的iOS和macOS平台。Objective-C中的UIKit框架是构建用户界面的基础,提供了丰富的控件和功能来创建iOS应用程序。...

    Objective-C基础教程第二版

    **Objective-C**是一种面向对象的编程语言,它在C语言的基础上增加了面向对象的功能,并且是开发iOS应用的主要语言之一。尽管Swift已经成为苹果官方推荐的新一代编程语言,但Objective-C仍然拥有大量的代码库和丰富...

    基于C语言的学习笔记(附代码)

    这份学习笔记涵盖了C语言的基础、高级、系统和工具四个部分,旨在帮助读者全面理解和掌握C语言的各个方面。 **第一部分:语言** 1. **数据类型**: - `char`: 8位有符号整数,可表示ASCII字符。 - `short`: 16位...

    C 学习笔记1

    【C语言学习笔记1】 本笔记主要涵盖了C语言的基础、高级特性和系统级知识,以及相关的开发工具。以下是对各个部分的详细说明: **第一部分:语言基础** 1. **数据类型** - `char`:有符号8位整数,通常用来存储...

    iOS 学习OC语言部分,代码和笔记,超详细

    在iOS开发领域,Objective-C(简称OC)是苹果公司官方支持的主要编程语言之一,尤其对于老版本的系统,它是开发的基石。本压缩包提供的学习资料涵盖了OC语言的基础到高级特性,结合代码实例和详细笔记,是iOS开发者...

    iosdev:Objective-C,Swift,API,示例,书籍,工具

    Objective-C是苹果早在20世纪80年代就引入的语言,它是C语言的超集,带有面向对象的特性。尽管Swift在近几年已经成为苹果平台的主要编程语言,但Objective-C依然在很多现有代码库和项目中广泛使用。Objective-C的...

    iOS开发:从入门到精通的指南.docx

    - **Objective-C**:作为一种面向对象的语言,Objective-C是C语言的扩展,它引入了类、消息传递等概念。虽然Swift逐渐成为主流,但Objective-C仍然是许多现有项目的首选语言。 - **Swift**:Swift是由Apple开发的一...

    python学习笔记(一)-python简介.pdf

    Python是一种高级、通用的编程语言,它的设计理念强调代码的可读性和简洁的语法,特别是使用空格缩进划分代码块,而非使用大括号或关键字。Python是解释型、面向对象的动态类型语言,这使得它在很多领域都有广泛的...

    iOS 学习C语言部分,代码和笔记,超详细

    在iOS开发中,C语言的应用主要体现在Objective-C的类别(Category)和方法选择器(Selector)上,以及Core Foundation框架,该框架大量使用C语言编写,提供了一系列基础数据类型和系统服务。 这个压缩包中的“C课程...

    day01-Java入门

    2. **基础语法**:包括变量、数据类型、运算符、控制流程(如if条件语句、for和while循环)、数组等。 3. **类和对象**:理解面向对象编程的核心概念,如封装、继承和多态。 4. **异常处理**:学习如何捕获和处理...

    AS4AS学习笔记

    2. **AppleScript语法**:笔记会详细解释AppleScript的语法规则,包括数据类型(如文本、数字、列表等)、运算符、控制结构以及错误处理。 3. **面向对象编程**:AppleScript允许通过对象模型与应用程序交互,笔记...

    Linux下的C编程基础.pdf

    - **强大的功能集:** 提供了丰富的数据类型和控制结构,包括但不限于数组、结构体、联合体、指针等,同时具备图形功能和高效的计算逻辑。 - **极高的可移植性:** C语言的硬件无关性意味着可以在不同的操作系统和...

    front-end-developer:前端开发,引入开发知识体系文档整理

    总的来说,这份"front-end-developer"文档可能是一个全面的前端开发者学习资源,涵盖了从基础知识到高级工具和技术的广泛内容,对于希望深入了解前端开发的人来说,是一份宝贵的资料。通过系统学习,开发者可以提升...

    redis 的学习笔记A

    它支持丰富的数据类型,如字符串、列表、集合、有序集合和哈希,这使得在设计解决方案时可以充分利用这些数据结构。此外,Redis还支持发布订阅模式、事务、lua脚本等功能,增强了其实用性。 3. Redis与Memcached的...

    CS193P笔

    在iOS开发中,Objective-C曾是主要的编程语言,它是一种面向对象的语言,有着C语言的基础并加入了Smalltalk的特性。笔记可能会介绍Objective-C的基本语法,如消息传递、类和对象、协议、类别等概念。随着Swift的推出...

    C语言精华ppt课件.ppt

    C语言的出现使得Unix操作系统得以迅速普及,同时也催生了后续许多其他高级语言,如C++、Objective-C、C#等。 2. C语言的发展 随着C语言的成功,其影响力不断扩大。1988年,美国国家标准协会(ANSI)制定了C语言的...

Global site tag (gtag.js) - Google Analytics