use gnustep objective-c

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

  1. 专注于概念,而不是迷失在语言技术细节中
  2. 编程语言的目的是成为一个更好的程序员; 也就是说,在设计和实现新系统以及维护旧系统方面变得更加有效

the basic structure of objc program has

  1. header preprocess
  2. interface
  3. implementation
  4. method
  5. variable
  6. declare and expression
  7. 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

  1. basic integer set and float set
  2. enum type
  3. void type
  4. 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保持一致,这里比较简单

  1. https://www.yiibai.com/objective_c/objective_c_operators.html#article-start

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

  1. 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;
}
  1. 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;
}
  1. 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;
}
  1. 指针
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 );
  1. 字符串
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);
  1. 有机会完善对Foundation的使用吧,记住上面的链接足够入门了
  2. 感兴趣的方向可能是拿它做server side吧

[important] my code style using application.make

  1. 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
  1. r.sh for simple run script or r.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
  1. simple project文件结构
bash 复制代码
.
├── GNUmakefile
├── main.m
├── Person.m
├── readme.md
└── r.sh
# 如果复杂可以添加文件夹
# 对于每一个.h .m的配对,我认为如果是简单的类的话,直接写成.m就可以了,不要写头文件了
# .m文件都应该是import,少用include
  1. 其他非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的其他说明

  1. 在c上添加的东西:类,协议,id和nil,OO里的他基本也有,消息传送到对象的机制
  2. 他留存的生命力: Foundation + 完全兼容c语言 + 一些小小组件,但是可能增加复杂度,比如makefile的编写
  3. NSObject更像一个java接口,c++抽象类,就是他的很多方法可以被重写,也可以被继承者直接使用

code reference

  • the above link
相关推荐
良技漫谈2 天前
Rust移动开发:Rust在iOS端集成使用介绍
后端·程序人生·ios·rust·objective-c·swift
向往的生活--7 天前
导航栏渐变色iOS
macos·objective-c·cocoa
MrZWCui9 天前
iOS18 取消/适配TabbarController缩放动画
学习·ios·objective-c·xcode·ios18
辰风已久9 天前
C++(基于C语言)
macos·objective-c·cocoa
名字不要太长 像我这样就好9 天前
【iOS】SDWebImage
macos·ios·开源·objective-c
小白学大数据11 天前
Objective-C 音频爬虫:实时接收数据的 didReceiveData_ 方法
数据库·爬虫·objective-c·音视频
名字不要太长 像我这样就好12 天前
【iOS】使用AFNetworking进行网络请求
开发语言·ios·objective-c·cocoa
耶耶耶耶耶~12 天前
深度探索C++对象模型
c++·objective-c
Morgana_Mo15 天前
iOS_响应者链 Responder Chain
ios·objective-c·1024程序员节
skylin1984010115 天前
iOS调试真机出现的 “__llvm_profile_initialize“ 错误
ios·objective-c·调试·1024程序员节