NSString和NSLog基本使用
/**
NSLog函数
作用:是prinf函数的增强版,
语法:NSLog(@"", 变量列表)
OC中设计了一个更好的用来存储字符串的1个类型,NSString
NSString类型的指针变量专门 用来存储OC字符串的地址
OC的字符串常量必须要使用1个前缀@符号
@"jack"这是1个OC的字符串常量
NSString类型的指针变量,只能存储OC字符串的地址
NSLog函数的第一个参数1个oc字符串,所以NSLog函数的第一个实参应该以@符合开头
如果要使用NSLog函数输出OC字符串的值,那么使用占位符%@
NS前缀
NextStep ---> Cocoa ---> Foundation框架中
@符号
1.将c字符串转换oc字符串
jack ---> @jack
2.oc中的绝大部分的关键字都是以@符号开头
*/
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSLog(@"hello world");
NSString *str = @"hello";
NSLog(@"字符串:%@", str);
return 0;
}
OC数据类型
/**
oc中的数据类型
1.基本数据类型
int, double, float, char
2.构造类型
数组,结构体,枚举
3.指针类型
int * p1
4.空类型
void
5.typeof自定义类型
6.bool类型
YES 1, NO 0
一般情况下bool类型的变量用来存储条件表达式的结果
7.boolean true, false
8.class类型,类
9.id类型 万能指针
10.nil 与null差不多
11.sel方法选择器
12.block代码段
*/
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
int num = 10;
BOOL flag = true;
//Boolean f = false; //unsigned char b1 = 0
if (flag) {
NSLog(@"YES...%d",num);
} else {
NSLog(@"NO...");
}
}
类和对象
类定义
/**
1.定义类的语法
a 位置,直接写在源文件中,不要写在main函数中
b 类的定义分为两个部分
-> 类的声明
@inteface 类名: NSObject
{
这类事物具有共同的特征,将他们定义为变量
}
功能就是1个方法,将方法的声明写在这里
@end
-> 类的实现
@implementation 类名
将方法的实现写在这里
@end
c 几点注意
类必须有声明和实现
类名用描述事物的名称命名,类名首字母大写
NSObject照写
用来表示这类事物的共同特征的变量必须要定义在@interface的{}中
定义在{}中用来表示这类事物的共同的特征的变量叫属性
语法是固定的
类是无法直接使用的,如果非要使用这个类的话,就必须要先找到这个类中的1个具体存在,再使用这个对
创建对象:
类名 *对象名 = [类名 new];
Person *p1 = [Person new];
根据Person这个类的模板,创建了1个对象名字叫p1
p1对象的特点:
可以直接使用,
类有的东西,对象也有
如何使用对象:
如何访问对象的属性:
1)默认对象的属性不允许被外界访问
如果允许对象的属性可以被外界访问,那么就在声明属性时加@public
2)访问对象的属性的方式
对象名->属性=值
*/
#import <Foundation/Foundation.h>
// 类声明
@interface Person : NSObject
{
@public
NSString * name;
int age;
NSString * address;
NSString * phone;
}
// 方法声明:表示类的功能
@end
// 类实现
@implementation Person
// 方法实现
@end
int main(int argc, const char* argv[]) {
// 创建对象
Person *p1 = [Person new];
p1->name=@"明太祖朱元璋";
p1->age=10;
p1->address=@"北京市";
p1->phone=@"18933322234";
NSLog(@"name:%@",p1->name);
NSLog(@"age:%d", p1->age);
NSLog(@"=====================");
(*p1).name=@"汉高祖刘邦";
(*p1).address=@"北平";
(*p1).age = 11;
NSLog(@"(*p1.age)age:%d", (*p1).age);
NSLog(@"name:%@",(*p1).name);
NSLog(@"address:%@",(*p1).address);
return 0;
}
方法声明
/**
方法的声明
// 类声明
@interface 类名 : NSObject
{
属性:表示类的特征
}
/方法声明:表示类的功能
@end
类实现
@implementation 类名
// 方法实现
@end
无参数的方法:
声明
位置:在@interface的大括号的外面
语法:- (返回值类型) 方法名称; - (void) study; 表示声明了一个无返回值并且无参数的方法,方法名字run
实现
位置:@implementation
语法:将方法的声明拷贝到@implementation中,去掉分号追加一对{...}
- (void) study {}
调用:[p1 study];
带一个参数的方法
声明语法:
- (返回值) 方法名:(参数类型) 形参名;
- (void) eat:(NSString *) foodName;
定义了1个方法,这个方法没有返回值,这个方法名eat:
这个方法有1个参数,类型是NSString* 类型的,参数的名字叫foodName
调用:
a.方法是无法直接调用的,因为类是不能直接使用的,必须先创建对象,那么这个对象中就有类中的属性和方法了,就可以调用对象的方法了
b.调用语法:
[对象名 方法名: 实参名]; [p1 eat:@"米饭"];
方法头中的数据类型都要用1个{}括起来
- (返回值类型) 方法名:(参数类型) 参数名
带多个参数的方法
声明:
语法:
- (返回值类型) 方法名: (参数类型) 参数名1: (参数类型) 参数名2: (参数类型) 参数名3....;
- (int) sum: (int) num1 :(int) num2;
表示声明了1个方法,这个方法的返回值类型是int类型的
方法名叫 sum: :
有两个参数,参数类型都是int类型,参数名叫 num1, num2
实现:
// 多个参数的方法实现
- (int) sum: (int) num1 :(int) num2 {
int s=num1+num2;
return s;
}
调用:
a.方法是无法直接调用的,因为类是不能直接使用的,必须先创建对象,那么这个对象中就有类中的属性和方法了,就可以调用对象的方法了
b.调用带多个参数的语法
[对象名 方法名:实参1:实参2:实参3];
int i = [p1 sum:10 :11 :12];
带参数的方法声明的规范:
1.如果方法只有1个参数,要求最好这个方法的名字叫 xxxwith
这样写的话,那么调用方法的时候看起来就像是1条完整的语句,提高了代码的阅读性。
2.如果方法有多个参数,建议这个方法名:
方法名with:(参数类型) 参数名 and: (参数类型) 参数名 and:(参数类型) 参数名
*/
#import <Foundation/Foundation.h>
// 类声明
@interface Person : NSObject
{
@public
NSString * name;
int age;
NSString * address;
NSString * phone;
}
// 方法声明:表示类的功能
- (void) study;
// 一个参数的方法声明
- (NSString *) eat:(NSString *) foodName;
// 多个参数的方法声明
- (int) sumWith: (int) num1 and:(int) num2 and:(int) num3;
@end
// 类实现
@implementation Person
// 方法实现
- (void) study {
NSLog(@"这是一个学习方法的实现");
}
// 一个参数的方法实现
- (NSString *) eat:(NSString *) foodName {
NSLog(@"主人在吃食物方法,他正在吃:%@",foodName);
return @"返回了eat吃的方法";
}
// 多个参数的方法实现
- (int) sumWith: (int) num1 and:(int) num2 and:(int) num3 {
int s=num1+num2+num3;
return s;
}
@end
int main(int argc, const char* argv[]) {
// 创建对象
Person *p1 = [Person new];
[p1 study];// 方法调用
NSString* eat= [p1 eat:@"黄焖鸡米饭"];
NSLog(@"eat返回了:%@", eat);
int i = [p1 sumWith:10 and:11 and:12];
NSLog(@"i=%d",i);
return 0;
}
其他注意事项
/**
1.在方法的实现中,可以直接访问属性
2.同1个类的多个对象之间毫无关系
属性的值是不会相互影响的
3.在方法的实现中,可以直接访问属性
在方法中访问的属性是谁的属性呢?
这个方法是通过哪个对象调用的,那么方法中的直接访问的属性就是哪个属性
4.案例
定义一个学生类
属性:体重
方法:跑步,每跑一次,这个学生对象的体重-1
吃饭:吃饭一次,体重+1
*/
#import <Foundation/Foundation.h>
// 类声明
@interface Person : NSObject
{
@public
NSString * name;
int age;
NSString * address;
NSString * phone;
double weight;
}
- (void) study;
@end
// 类实现
@implementation Person
- (void) study {
NSLog(@"我的名字是:%@,今年%d岁了!", name, age);
}
@end
int main(int argc, const char* argv[]) {
// 创建对象
Person *p1 = [Person new];
(*p1).name = @"李世民";
(*p1).age = 66;
[p1 study];// 方法调用
Person *p2 = [Person new];
(*p2).name=@"努尔哈赤";
(*p2).age=62;
(*p2).address=@"奉天";
[p2 study];// 方法调用
return 0;
}
对象在内存中的存储
/**
1.内存中的五大区域
栈:存储局部变量
堆:程序员手动申请的字节空间 malloc , calloc , realloc函数
BSS段:存储未被初始化的全局变量、静态变量
数据段(常量区):存储已被初始化的全局静态变量、常量数据
代码段:存储程序的代码
2.类加载
1)在创建对象时,肯定要访问类的
2)声明1个类的指针变量也会访问类的
在程序运行期间,当某个类1次被访问到时,会将该类存储到内存中代码段区,这个过程叫类加载
3.nil和null
null可以作为指针变量的值
如果1个指针变量的值是null值代表这个指针不指向内存中的任何1块空间
null其实等价于0, null其实是个宏,就是0
4.nil
只能作为指针变量的值,代表这个指针变量不指向内存中的任何空间。
nil 其实也等价于0,也是个宏
所以null和nil其实是一样的
使用建议:
c指针用null
int *p1=null; p1指针不指向内存中的任何空间
oc类指针用nil
Person *p1=nil;p1不指向任何对象
5.如果1个类指针的值为nil,代表这个指针不指向任何对象
Person *p1=nil;
这个使用,如果通过p1指针去访问p1指针指向的对象属性,这时会运行报错
多文件开发:
推荐:把一个类写在一个模块中,一个模块至少包含两个文件
头文件 类声明
实现文件 类实现
*/
#import <Foundation/Foundation.h>
#import "person.h"
int main(int argc, const char * argv[]) {
Person *p1 = [Person new];
(*p1).name = @"申公豹";
(*p1).age = 10;
[p1 sayHi];
int *p12= NULL; // int *p2 = 0;
if(nil==NULL) {
NSLog(@"null==nil....");
}
return 0;
}
多文件编写
多文件开发:
推荐:把一个类写在一个模块中,一个模块至少包含两个文件
头文件 类声明
实现文件 类实现
头文件
类实现
主函数
对象作为方法的参数
main.m
/**
1.对象和方法
对象作为方法的参数,对象作为方法的返回值
2.类的本质是我们自定义的1个数据类型
3.既然类是1个数据类型,那么类就可以作为方法的参数
- (void) study: (Dog *) dog;
这个是完全没有问题的
语法注意:
1.当对象作为方法参数时,参数应该怎么写,参数类型是类指针
- (void) study: (Dog *) dog;
2.调用方法时,如果方法的参数是1个对象
那么给实参的时候,实参要求也必须是1个符合要求的对象
*/
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Dog.h"
int main(int argc, const char * argv[]) {
Student *s = [Student new];
Dog *dog = [Dog new];
s->name = @"朱元璋";
s->age = 33;
dog->name=@"金毛";
dog->color=@"黄色";
[s study:dog];
return 0;
}
这里创建了两个类,Dog和Student