显示标签为“Object-C”的博文。显示所有博文
显示标签为“Object-C”的博文。显示所有博文

2015年8月26日星期三

使用 @class 导入类

使用 @class来导入类。

应用场景: B类导入A类

A.h里 声明 @class

@class B;

A.m里 注入import

import "B.h"

[B b];

2015年7月7日星期二

malloc的使用

char m;
scanf(" %c",&m); //前面加空格是为了去掉空格、回车等操作
NSLog(@"the character is %c",m);

    上面这个程序是各位比较熟悉的两个方法一个输入、一个输出,但是如果我改一下改成

char *m;
NSLog(@"\n请输入一个字符");
scanf(" %c",m);
NSLog(@"\nthis is %c",*m);

    是否正确呢,编译时是否会报错,运行时是否会出问题?
    其实这个程序,如果编译的时候不会出现异常,但是如果运行的话,会出现运行时异常(出现lldb命令,使用kill命令结束即可),原因是就是我们定义了一个char指针m,这个指针没有进行初始化赋值,导致程序运行时无法找到存储这个字符的内存空间,如果改成

char *m;
m=(char *)malloc(sizeof(char));//malloc()动态分配内存,malloc分配内存的首地址,然后赋值给m
NSLog(@"\n请输入一个字符");
scanf(" %c",m);
NSLog(@"\nthis is %c",*m);

      如果使用malloc方法进行分配空间之后,程序便可以正常进行,sizeof方法获得对应类型的空间大小

   趁热再来一发,因为使用malloc进行动态分配空间,所以我们可以使用char指针输出字符串,如下:
char *a;
a=(char *)malloc(sizeof(char)*100); //动态分配100个连续的char内存地址
NSLog(@"\n请输入一个字符串");
scanf(" %s",a);
NSLog(@"\nthis is %s",a);

C语言memset函数详解与误用

memset为内存填充函数,包含在<string.h>头文件中,可以用它对一片内存空间进行初始化,其原型为  
void *memset(void *s, int v, size_t n);  
英文释义如下: 
Copies the value v (converted to type unsigned char) to the first n bytes pointed to by s; returns s.  
这里s可以是数组名,也可以是指向某一内在空间的指针;v为要填充的值;n为要填充的字节数,通常为sizeof(s); 
使用memset时要注意的是,memset是逐字节进行填充,所以s一般为char *型。
对于其它类型的s,可以填充的值有两个,0和-1。这是因为计算机中用二进制补码表示数字,0的二进制补码为全0,-1的二进制补码为全1。如果要初始化为其它的值,可以用一个for循环,如下:
 for (int i=0; i<n; i++)
     s[i] = v; 
  
memset() 函数常用于内存空间初始化。如:
char str[100];
memset(str,0,100);
memset可以方便的清空一个结构类型的变量或数组。
  如:
  struct sample_struct
  {
  char csName[16];
  int iSeq;
  int iType;
  };
  对于变量
  struct sample_strcut stTest;
  一般情况下,清空stTest的方法:
  stTest.csName[0]='/0';
  stTest.iSeq=0;
  stTest.iType=0;
  用memset就非常方便:
  memset(&stTest,0,sizeof(struct sample_struct));
  如果是数组:
  struct sample_struct TEST[10];
  则
  memset(TEST,0,sizeof(struct sample_struct)*10);
  
对于赋特定的值,需注意
 char a[5];
     memset(a,1,5);  //成功赋值为0x01
     int a[5];
     memset(a,1,5);//这里改成memset(a,1,5 *sizeof(int))也是不可以的 
   因为第一个程序的数组a是字符型的,字符型占据内存大小是1Byte,而memset函数也是以字节为单位进行赋值的。
 而第二个程序a是整型的,使用memset还是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。


 memset,memcpy,strcpy 的区别
一.函数原型
   strcpy
   extern char *strcpy(char *dest,char *src);
   #include <string.h>
   功能:把src所指由NULL结束的字符串复制到dest所指的数组中
   说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
   返回指向dest的指针


memcpy
extern void *memcpy(void *dest,void *src,unsigned int count);
#include <string.h>
   功能:由src所指内存区域复制count个字符串到dest所指内存区域.
   说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针.
 
   memset
   extern void *memset(void *buffer,int c,int count);
   #include <string.h>
   功能:把buffer所指内存区域的前count个字节设置成字符c
   说明:返回指向buffer的指针.



二.区别
    memset 用来对一段内存空间全部设置为某个字符,一般用于在对定义的字符串初始化为' '或者'\0';
    例: char a[100];
          memset(a,'\0',sizeof(a));
   
   memcpy 是用来做内存拷贝,可以用来拷贝任何数据类型的对象,可以指定拷贝的数据长度;
   例:
           char a[100],b[50];
           memcpy(b,a,sizeof(b));   //注意:如果使用sizeof(a),会造成内存溢出
   mem是一段内存,他的长度,必须自己记住.memcpy是见着什么拷贝什么。
   
    strcpy 就只能拷贝字符串,它遇到'\0'就结束拷贝;
      例:char a[100],b[50];
              strcpy(a,b);
              如用strcpy(b,a)要注意a中的字符串长度(第一个'\0'之前) 是否超过50,如果超过,则会造成b的
内存溢出.它是不会拷贝'\0'的,所以一般还有加一个语句:
              *a='\0';
 
三.使用技巧
      memset 可以方便的清空一个数据结构的变量或数组.
      如:
        struct sample_struct
       {
              char csName[16];
              int iSeq;
              int iType;
       };
       对于变量
       struct sample_struct stTest;
       一般情况下,初始化stTest的方法:
        stTest.csName[0]='\0';
        stTest.iSeq=0;
        stTest.iType=0;
    而用memset:
       memset(&stTest,0,sizeof(struct sample_struct));
    如果是数组:
    struct sample_struct TEST[100];
    memset(TEST,0,sizeof(struct sample_struct)*100);

strcpy是拷贝字符串,以\0为标志结束(即一旦遇到数据值为0的内存地址拷贝过程即停止)
strcpy的原型为
char *strcpy(char *dest, const char *src)
而memcpy是给定来源和目标后,拷贝指定大小n的内存数据,而不管拷贝的内容是什么(不仅限于字符)
memcpy的原型为
void *memcpy(void *dest, const void *src, size_t n);

2015年6月24日星期三

protocol 协议使用

protocl 协议跟java的接口差不多的概念


首先要定义
@protocol PainterSetupViewDelegate;
这是定义接口
@protocol PainterSetupViewDelegate<NSObject>

- (void)painterSetupViewController:(PainterSetupViewController *) 
        controller setColor:(UIColor *)color;
- (void)painterSetupViewController:(PainterSetupViewController *) 
        controller setWidth:(float)width;
@end


使用他的时候

.h里定义他
@interface ViewController : UIViewController<PainterSetupViewDelegate>
{
    
}
@end


.m里就得实例化他了

@implementation ViewController



- (void)viewDidLoad
{

    [super viewDidLoad];
}


-(IBAction)PenClick         //  Pen Type
{
    [(MainPainterView *)self.view setpCurType:PEN];
    
}
-(IBAction)LineClick       // Line Type
{
    [(MainPainterView *)self.view setpCurType:LINE];
}

-(IBAction)CircleClick     // Circle Type
{
    [(MainPainterView *)self.view setpCurType:CIRCLE];
    
}

-(IBAction)EraseClick     // Erase Type
{
    [(MainPainterView *)self.view setpCurType:ERASE];
    
}

-(IBAction)RectangleClick     // Taegeuk Type
{
    [(MainPainterView *)self.view setpCurType:RECTANGLE];
    
}



-(IBAction)SetupClick
{
    if (pPainterSetupViewController == nil) {
            
        PainterSetupViewController *viewController = [self.storyboard     instantiateViewControllerWithIdentifier:@"PainterSetupViewController"];
        
        viewController.delegate = self;
        pPainterSetupViewController = viewController;
    }
    [self presentViewController:pPainterSetupViewController animated:YES completion:nil];
    
}


- (void)painterSetupViewController:(PainterSetupViewController *) controller setColor:(UIColor *)color
{
    [(MainPainterView *) self.view setpCurColor:color];
}

- (void)painterSetupViewController:(PainterSetupViewController *) controller setWidth:(float)width
{
    [(MainPainterView *) self.view setpCurWidth:width];
}



@end

2015年4月20日星期一

方法参数的 命名方式

有时候方法名里也会设置位 参数名,看看以下方法.

在方法Caculation中为 对二个参数设置名为 CurStatusCode了. 在看看方法使用方法。


2015年3月28日星期六

2015年3月26日星期四

객체 생성하기(alloc,release)

alloc와 release는 묶어서 나타나야 한다.

alloc는 메모리를 할당하는 것이고 release는 반납하겠다는 뜻이다.

예문
sample =[[MySample alloc] init];
[sample release];


@synthesize와@property

이두가지로 선언했다면 해당 메서드를 자동으로 생성하도록 하는 지시어다.

@synthesize 는 get와set를 생략한다

@dynamic은 부모클래스에서 @synthesize된 getter와 setter를 사용하겠다고 선언

Xcode 4.4부터 .h가 property가 선언되었다면 .m에서 @synthesize를 사용하지 않아도
"_"만 붙으면 해당 synthesize world=_world와 같은 효과이다.

property的 strong以及weak

property의  strong과 weak는 ARC(XCode 5)가 도입되면서 추간된거다

strong:은 새로운 객체를 도입하면 해당 객체는 무조건 ratain된다.즉 해당객체를 사용하지 않으면
메모리가 자동 해제된다 .

weak: 해당객체가 메모리에서 해제될 때 자동으로 nil값을 대입해 준다


下面的描述写的比较明白。

property 中的strong 与weak

strong关键字与retain关似,用了它,引用计数自动+1,用实例更能说明一切

@property (nonatomic, strong) NSString *string1;   
@property (nonatomic, strong) NSString *string2;  

有这样两个属性,

 @synthesize string1;   
@synthesize string2;  


猜一下下面代码将输出什么结果?

self.string1 = @"String 1";   
self.string2 = self.string1;   
self.string1 = nil;  
NSLog(@"String 2 = %@", self.string2);  


结果是:String 2 = String 1

由于string2是strong定义的属性,所以引用计数+1,使得它们所指向的值都是@"String 1", 如果你对retain熟悉的话,这理解并不难。

接着我们来看weak关键字:
如果这样声明两个属性:

@property (nonatomic, strong) NSString *string1;   
@property (nonatomic, weak) NSString *string2;  

并定义 
@synthesize string1;   
@synthesize string2;  



再来猜一下,下面输出是什么?

 self.string1 = @"String 1";   
self.string2 = self.string1;   
self.string1 = nil;  
NSLog(@"String 2 = %@", self.string2);  

结果是:String 2 = null

分析一下,由于self.string1与self.string2指向同一地址,且string2没有retain内存地址,而self.string1=nil释放了内存,所以string1为nil。声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。在c/c++开发过程中,为何大牛都说指针的空间释放了后,都要将指针赋为NULL. 在这儿用weak关键字帮我们做了这一步。