first app
c
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSLog(@"first start");
[pool drain];
return 0;
}
tech
- 专注于概念,而不是迷失在语言技术细节中
- 编程语言的目的是成为一个更好的程序员; 也就是说,在设计和实现新系统以及维护旧系统方面变得更加有效
the basic structure of objc program has
- header preprocess
- interface
- implementation
- method
- variable
- declare and expression
- comment
use interface and implementation
c
#import <Foundation/Foundation.h>
@interface SampleClass:NSObject
- (void)sampleMethod;
@end
@implementation SampleClass
- (void)sampleMethod
{
NSLog(@"hello from sample class");
}
@end
int main()
{
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass sampleMethod];
return 0;
}
type system
- basic integer set and float set
- enum type
- void type
- derive type include pointer, array, struct, union, function
c
// so far we still use Foundation
int main()
{
NSLog(@"type int takes %d\n",sizeof(int));
NSLog(@"Storage size for float : %d , maxval=%f \n", sizeof(float), FLT_MAX);
int c_i = 1;
NSInteger i = 1;
NSLog(@"%d\n",i);
}
support c type variable and c type function
c
void test()
{
printf("this is c type function\n");
}
#define DEBUG YES
const int G_error_no = 1;// notice that upper case of const is a good style
int main()
{
test();// cosume the c type function
NSLog(@"err no: %d\n",G_error_no);
}
基本运算符(算术,逻辑,位运算)的支持是和c保持一致,这里比较简单
method in objc
- (return_type) method_name:( argumentType1 )argumentName1
joiningArgument2:( argumentType2 )argumentName2 ...
joiningArgumentn:( argumentTypen )argumentNamen {
body of the function
}
c
// skip the class declare and impl
// notice that java style is good style
// and joiningArgument just needed to take its place,but not a real name of argument
-(int)max:(int)num1 secondNumber:(int)num2{
if (num1 > num2)return num1;
else return num2;
}
int main(){
// call the method,for example using a class
SampleClass *sampleClass = [[SampleClass alloc]init];
int ret =
[sampleClass max:1 secondNumber:2];
printf("%d\n",ret);
}
// 函数参数按值传参和按引用/指针传参是支持的,有机会在深入一遍c语言
[deprecate] block is an instance (some error with enable blocks using -fblocks)[notfix]
仅表示单个任务或行为单元而不是方法集合是有意义的(using block),它允许创建不同的代码段,这些代码段可以传递给方法或函数,就像它们是值一样。 块是Objective-C对象,因此它们可以添加到NSArray或NSDictionary等集合中。 它们还能够从封闭范围中捕获值,使其类似于其他编程语言中的闭包或lambda
returntype (^blockName)(argumentType);
returntype (^blockName)(argumentType)= ^{};
demo
c
#import <stdio.h>
#import <Foundation/Foundation.h>
int main()
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
printf("yas\n");
id undef = nil;
if (undef == nil)
{
printf("undef is nil\n");
}
float versionNumber = [NSString version];
printf("%f\n",versionNumber);
NSString *w = @"Brainstorm";
NSString * gprChannel = [NSString stringWithFormat:@"let me be %d",1];
// use c style string
char * c_str = "yes";
NSString *str = [NSString stringWithCString:c_str];// convert c string to NSString class
NSLog(@"%@",str);
NSMutableString *s = AUTORELEASE ([NSMutableString new]);
// Note. Static strings created with the @"..." construct are always immutable.
[pool drain];
return 0;
}
simple read file
c
#include <Foundation/Foundation.h>
#include <stdio.h>
int
main (void)
{
CREATE_AUTORELEASE_POOL(pool);
NSString *string;
NSString *filename = @"/home/etcix/hello-objc/test.txt";
string = [NSString stringWithContentsOfFile: filename];
if (string == nil)
{
NSLog (@"Problem reading file %@", filename);
/*
* <missing code: do something to manage the error...>
* <exit perhaps ?>
*/
}
else {
printf("read file ok\n");
}
/*
* <missing code: do something with string...>
*/
RELEASE(pool);
return 0;
}
examples
- methods
c
#import <Foundation/Foundation.h>
#include <stdio.h>
// interface
@interface SampleClass:NSObject
{
//all variable in here
int age;
}
@property(nonatomic) int age;//property可选聚合参数:readonly,assign,retain,atomic,readwrite(默认)
-(int)max:(int)lhs rhs:(int)rhs;//name of method is `max: rhs:`,usage:max: 1 rhs: 2
@end
// impl
@implementation SampleClass
@synthesize age;//动态生成get,set,注意要和属性名字一样,先property后synthesize
-(int)max:(int)lhs rhs:(int)rhs
{
return lhs>rhs ? lhs : rhs;
}
@end
int main()
{
SampleClass *sample = SampleClass.new;// 点语法调用,通常是在@property的属性上调用,其他方法一般不可用,而且区别于c++的是,sample是指针,但是访问属性却是点语法
int a,b;
printf("two integer value should input\n");
scanf("%d %d",&a,&b);
int ret = [sample max:a rhs: b];
printf("the ret is %d\n",ret);
sample.age = 1;//set
printf("%d\n",sample.age);//get
return 0;
}
- NSNumber
c
#import <Foundation/Foundation.h>
#import <stdio.h>
@interface SampleClass:NSObject
-(NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b;
@end
// impl
@implementation SampleClass
-(NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b
{
float number1 = [a floatValue];
float number2 = [b floatValue];
float product = number1 * number2;
NSNumber * result = [NSNumber numberWithFloat:product];
return result;
}
@end
int main()
{
CREATE_AUTORELEASE_POOL(pool);
SampleClass *sample = [[SampleClass alloc] init];
NSNumber *a = [NSNumber numberWithFloat:5.6];
NSNumber *b = [NSNumber numberWithFloat:1.6];
NSNumber *res = [sample multiplyA:a withB:b];
NSString *str = [res stringValue];
NSLog(@"the res is %@",str);// 可见objc语法的冗长,但也证明了类型丰富
RELEASE(pool);
return 0;
}
- array
c
#import <Foundation/Foundation.h>
#import <stdio.h>
@interface SampleClass:NSObject
-(int *)getRandom;
@end
// impl
@implementation SampleClass
-(int *)getRandom
{
static int arr[10];
int i;
srand((unsigned)time(NULL));
for(i = 0; i< 10;++i)
{
arr[i] = rand();
NSLog(@"r[%d] = %d\n",i,arr[i]);
}
return arr;//return array
}
@end
int main()
{
CREATE_AUTORELEASE_POOL(pool);
int *p;
SampleClass *sample = [[SampleClass alloc] init];
p = [sample getRandom];// cosume generated array
// int i;
for(int i = 0; i < 10; i++)
{
NSLog(@"*(p+%d):%d\n",i,*(p + i));//use pointer of array
}
RELEASE(pool);
return 0;
}
- 指针
c
int var1;
char var2[10];
NSLog(@"Address of var1 variable: %x\n", &var1 );
NSLog(@"Address of var2 variable: %x\n", &var2 );
int var = 20; /* 变量定义 */
int *ip; /* 指针变量声明 */
ip = &var; /* 在指针变量中存储 var 的地址*/
NSLog(@"Address of var variable: %x\n", &var );
/* 存储在指针变量中的地址 */
NSLog(@"Address stored in ip variable: %x\n", ip );
/* 使用指针访问该值 */
NSLog(@"Value of *ip variable: %d\n", *ip );
- 字符串
c
NSString *str1 = @"hello";
NSString *str2 = @"world";
NSString *str3;
int len;
str3 = [str2 uppercaseString];
NSLog(@"str3: %@",str3);
str3 = [str1 stringByAppendingFormat:@" append to str1"];
NSLog(@"str3: %@",str3);
len = [str3 length];
NSLog(@"str3: %@,len: %d",str3,len);
- 有机会完善对Foundation的使用吧,记住上面的链接足够入门了
- 感兴趣的方向可能是拿它做server side吧
[important] my code style using application.make
- GNUmakefile
bash
# !!!NOTE: this is application makefile for simple project, read it and just modify a little
GNUSTEP_MAKEFILES = /usr/share/GNUstep/Makefiles
SRC_DIR = . # this folder is source code directory, CAN MODIFY
include ${GNUSTEP_MAKEFILES}/common.make
APP_NAME = main # name of application,CAN MODIFY
${APP_NAME}_HEADER_FILES =
${APP_NAME}_OBJC_FILES = $(SRC_DIR)/*.m #every .m file will be matched, CAN MODIFY
${APP_NAME}_RESOURCE_FILES =
include ${GNUSTEP_MAKEFILES}/application.make
r.sh
for simple run script orr.bat
on windows
bash
#r.sh
# I am not going to provide r.bat
make
openapp ./main.app #this name refer to GNUmakefile APP_NAME
- simple project文件结构
bash
.
├── GNUmakefile
├── main.m
├── Person.m
├── readme.md
└── r.sh
# 如果复杂可以添加文件夹
# 对于每一个.h .m的配对,我认为如果是简单的类的话,直接写成.m就可以了,不要写头文件了
# .m文件都应该是import,少用include
- 其他非application项目,如tool(command line tool)项目,我也提供一个参考的GNUmakefile吧
bash
#GNUmakefile for tool
GNUSTEP_MAKEFILES=/usr/share/GNUstep/Makefiles #on linux mint
include ${GNUSTEP_MAKEFILES}/common.make
TOOL_NAME = client # MODIFY
${TOOL_NAME}_HEADER_FILES = # ADD
${TOOL_NAME}_OBJC_FILES = client.m # MODIFY
include ${GNUSTEP_MAKEFILES}/tool.make
# still run for example
# make && ./obj/client
对GNUstep和objc的其他说明
- 在c上添加的东西:类,协议,id和nil,OO里的他基本也有,消息传送到对象的机制
- 他留存的生命力: Foundation + 完全兼容c语言 + 一些小小组件,但是可能增加复杂度,比如makefile的编写
- NSObject更像一个java接口,c++抽象类,就是他的很多方法可以被重写,也可以被继承者直接使用
code reference
- the above link