0%

NSMutableString不同于NSString,其值是可变的,因而对其操作时,不需要赋给其他对象来保存操作后的结果。

#import 

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        NSMutableString * mstr=[NSMutableString stringWithString:@"This is a NSMutableString Object"];
        NSLog(@"%@",mstr);
        
        //插入字符
        [mstr insertString:@"前缀 " atIndex:0];
        NSLog(@"%@",mstr);
        [mstr appendString:@" 后缀"];
        NSLog(@"%@",mstr);
        [mstr deleteCharactersInRange:NSMakeRange(0, 3)];
        //删除字符,并非字节,这里是删除前缀
        NSLog(@"%@",mstr);
        
        NSRange subRange=[mstr rangeOfString:@" 后缀"];
        if(subRange.location!=NSNotFound){
            [mstr deleteCharactersInRange:subRange];
        }
        //先找出range,再删除,如果找不到,返回的range的location值为NSNotFound
        //替换子串 replaceCharactersInRange接收器 使用方法类似,因为是通过range,所以该方法只会替换一次
        NSLog(@"%@",mstr);
        [mstr replaceOccurrencesOfString:@"t" withString:@"T" options:nil range:NSMakeRange(0, [mstr length])];
        //把所有的t替换成T
         NSLog(@"%@",mstr);
        NSMutableString * str2=[NSMutableString alloc];
        str2=[str2 initWithContentsOfURL:([NSURL URLWithString:@"http://www.pocketdigi.com"]) encoding:(NSUTF8StringEncoding) error:nil];
        //下载HTML页面
        NSLog(@"%@",str2);
        
    }
    return 0;
    
}

NSString是不可变字符串,一旦定义,就不可更改,重新赋值,并不是在原位置修改,而是新开辟一个空间存储,并把新地址赋给指针变量

#import 

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        NSString *str1=@"This is a String";
        
        NSLog(@"%@ ,长度:%d",str1,[str1 length]);
        //输出字符串及长度
        
        NSLog(@"取出第2个字符:%c",[str1 characterAtIndex:2]);
        
        NSRange range=NSMakeRange(1,6);
        //构建NSRange对象,描述是一个范围,用于截取子串或其他需要指定范围的方法,参数是开始的索引值,长度
        unichar  buffer[6];
        [str1 getCharacters:buffer range:range];
        //根据range,取出字符,存放于unichar数组中
        NSString *substr=[NSString stringWithCharacters:buffer length:6];
        //把unichar数组转成NSString对象        
        NSLog(@"从第1个字符开始,取出6个字符:%@",substr);
        NSLog(@"全部转换成小写:%@",[str1 lowercaseString]);
        NSLog(@"全部转换成大写:%@",[str1 uppercaseString]);
        
    }
    return 0;
    
}

#define与typedef功能类似,但它除了定义数据类型外,还可以定义给变量、语句等等定义,还可以包含参数。#define的原理是文本替换。 具体用法:

#define INTEGER int
//把int定义成INTEGER
#define PRINTNUM(i) NSLog(@"%d",i)
//把后面的输出语句定义成带参数的PRINTNUM
int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        INTEGER i=5;
        NSLog(@"%d",i);
        
        PRINTNUM(555);
        
        
    }
    return 0;
}

执行结果: 2012-02-07 15:12:29.011 hello[629:707] 5 2012-02-07 15:12:29.014 hello[629:707] 555 用##可以连接两个标记,如:当一个变量名由传进的参数和常量组成时,比如变量名为xn,n由参数传入,则可以写成x##n 用#可以创建一个C风格的常量字符串。

typedef可以为数据类型定义一个可读性更高的名字,用法如下:

typedef int Integer;
//给类型int取一个新名,叫Integer

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        Integer i=55;
        NSLog(@"%d",i);
        
        
    }
    return 0;
}

默认不加修饰的是@protected,即只能被该类及其子类访问 @public:所有类都可访问 @private:只能被自已访问,子类也不能访问 @package:这个不太理解,《Objective-C 2.0程序设计》书中原文”对于64位图像,可以在实现该类的图像的任何地方访问这个实例变量.”因为这本书是翻译自英文,我个人感觉翻译有问题. 使用方法,与Java略有不同:

@interface ClassA : NSObject
{
    int num;
    //默认@protected
@private
    //下面开始到@protected前,全是private
    int a;
    int b;
@protected
    int c;
    
}

原先我们都用以下代码来构建一个实例:

ClassA * a=[[ClassA alloc] init];

在Java中,这就相当于一个无参数的构造方法,如果接下来需要给实例变量赋值,我们可以直接写个带参数的构造方法. ClassA:

#import 

@interface ClassA : NSObject
{
    int num;
}
@property int num;
//自动封装属性
-(ClassA *)initWithNum:(int)n;
-(void)printNum;

@end

@implementation ClassA
@synthesize num;
-(ClassA *)initWithNum:(int)n
{
    self=[super init];
    //执行继承自父类的init
    [self setNum:n];
    //使用封装属性后自动生成的setNum方法,赋值
    return self;
}
-(void)printNum
{
    NSLog(@"%d",num);
}
@end

main.m

#import 
#import "ClassA.h"
//导入头文件

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        ClassA * a=[[ClassA alloc] initWithNum:20];
        //调用initWithNum,传入参数        
        [a printNum];
        
    }
    return 0;
}

判断两个对象是否同属于一个类:

[obj1 class] == [obj2 class]

判断一个对象是否属于一个类的实例:

[obj1 isMemberOf: [ClassName class]]

存储类说明符: auto 与static相反,变量的默认声明方式 const 声明常量,声明的同时必须赋值,因为不可改变 volatile 与const相反,明确告诉编译器,该变量的值会改变,避免编译器自动优化掉看似多余的赋值语句。 在使用过程中,对象或类的名字叫接收器(Receiver)方法名被称作选择器(Selector),如; [NSNumber numberWithInt:1] NSNumber是接收器,numberWithInt是选择器,之前直接叫对象,方法,以后的笔记中都会做修改。 未完待续…

在ClassB中使用ClassA ClassA:

#import 

@interface ClassA : NSObject
{
    int num;
}
@property int num;
//自动封装属性
@end

@implementation ClassA
@synthesize num;
@end

ClassB:

#import "ClassA.h"
//@class ClassA;
//如果没有调用ClassA中的方法,而只是用到了属性,就不需要import *.h文件,只需要使用@class 引入类,速度更快
@interface ClassB : NSObject
{
    ClassA *a;
}
-(void)initA:(ClassA *) aa;
-(void)printA;
@end

@implementation ClassB
-(void)initA:(ClassA *)aa
{
    a=[ClassA new];
    [a setNum:aa.num];
    //不直接赋值,是因为传过来的是指针,如果外部的ClassA对象被修改,这里的值会受到影响
     
}
-(void)printA
{
    NSLog(@"num的值为%d",a.num);
}
@end

使用:

#import 
#import "ClassB.h"
//导入头文件

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        ClassA *a=[ClassA new];
        a.num=5;
        NSLog(@"%d",a.num);
        
        ClassB *b=[ClassB new];
        [b initA:a];
        [b printA];
        
    }
    return 0;
}

本例ClassB继承自ClassA例 ClassA源代码:

#import 

@interface ClassA : NSObject
{
    int i;
}
-(void)initI;
-(void)printI;
@end

@implementation ClassA
-(void)initI
{
    i=100;
}
-(void)printI
{
    NSLog(@"i的值为%d",i);
}
@end

ClassB源代码:

#import "ClassA.h"

@interface ClassB : ClassA
-(void)addI:(int)n;
//增加自己的方法
@end

@implementation ClassB
-(void)addI:(int)n
{
    i+=n;
}
-(void)printI
{
    //重载Class中的printI方法
     NSLog(@"ClassB中重载方法 i的值为%d",i);
}
@end

main中使用方法:

#import 
#import "ClassA.h"
#import "ClassB.h"
//导入头文件
Boolean isSu(int);

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        ClassA *a=[ClassA new];
        [a initI];
        [a printI];
        ClassB *b=[ClassB new];
        [b initI];
        [b printI];
        //调用继承自ClassA的initI和自身重载的printI方法
        [b addI:50];
        //调用ClassB自身的方法,使i增加50
        [b printI];
    }
    return 0;
}

输出结果: 2012-02-06 15:04:55.527 hello[476:707] i的值为100 2012-02-06 15:04:55.529 hello[476:707] ClassB中重载方法 i的值为100 2012-02-06 15:04:55.530 hello[476:707] ClassB中重载方法 i的值为150

定义静态变量不需要先在interface中声明. 可以在两个位置定义,一个是在@implementation前一行或者后一行定义,另一个是在方法内部定义,当然,区别只在作用域. 代码如下:

//static int count=0;
@implementation Student
static int count=0;
-(void)pageCount
{
//   static int count=0;
    count++;
    NSLog(@"第%d个",count);
}

注释掉的位置也可以定义.所有的实例共享静态变量,也就是说,只要在一个实例中改变,另一个实例中也跟着改变.在方法中定义时,如果已经有实例执行过声明的那行,后面的实例就不会执行这行.所以结果不会先清零.