extern传值 ios

2019-07-03 07:20:31 weixin_34418883 阅读数 140

 ios 页面传值4种方式(一) 之全局变量

运用该方法1.解决了我在哈哈项目里查看详细XIB第一行不能显示hahaItem的问题~  鼓掌~~~~~
通用的是用代理的方式实现页面传值,但是有时候利用其它方式也可以很巧妙的解决问题,页面传值一共有4种方式:

1、使用全局变量, SharedApplication,定义一个变量来传递.

2、使用文件,或者NSUserdefault来传递

3、通过一个单例的class来传递

4、通过Delegate来传递。

 

一:定义

AppDelegate.h

@property (nonatomic, retain) DetailViewController *detailViewController;@property (nonatomic, retain) NSString *text;

 

二:实现

AppDelegate.m

@synthesize detailViewController = _detailViewController;@synthesize text;

如果有定义对象, 别忘了实例化

 

self.detailViewController = [[[DetailViewControlleralloc]init]autorelease];

 

三: 调用

保存

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];appDelegate.text = textField.text;

 

使用

AppDelegate *app = [UIApplication sharedApplication].delegate;NSLog(@"%@", app.detailViewController.text);

 

在别的页面中,可以直接使用引用和基本数据类型;

转载于:https://www.cnblogs.com/someonelikeyou/p/3352550.html

2013-09-23 00:51:00 weixin_30745641 阅读数 6

1 设置委托(代理模式)
   
   建一个委托testViewDelegate.h
   #import
//b中的参数传到a
//设置委托方法,例如本文件
//在b中.h描述NSObject * delegate;  .m中调委托方法
//在a中设置b的控制器实现delegate,eg--aViewControll.delegate=self;
//然后在a中赋值

@protocol testViewDelegate
@optional
-(void)outPut:(NSString *)theTitle;

@end

2 extern          
interface之前定义extern NSString *strZhi;
.h
extern NSString *strZhi;
@interface OneViewController : UIViewController {
}
@end

.m
 NSString *strZhi=@"额的神阿,传值了";
@implementation OneViewController

在SplashViewController.m中定义一个变量是这样的

#import "SplashViewController.h"

NSString* meString=@"123";

@implementation SplashViewController

// NSString* meString=@"123";

.................

这两 个地方都行

 

如果在另外的类iTennisViewController.m中要用到这个类中的meString时只需在iTennisViewController.m中写成这样

#import "iTennisViewController.h"

extern NSString* meString;

@implementation iTennisViewController

即可

这样你在iTennisViewController.m中直接打印meString,你会发现 是123,当然你也可以对meString重新斌值 ,就是说meString虽然定义在SplashViewController.m中但好像是公共的,也称为全局变量吧


3 NSUserDefaults
.h
#define myAvgcost @"myavgcost"
.m
[[NSUserDefaults standardUserDefaults] setObject:p_Avgcost_arr forKey:myAvgcost];//写道磁盘
传到另一个类
NSArry *myAvgcost_arr=[[NSUserDefaults standardUserDefaults] arrayForKey:myAvgcost];
4
 单例
主要是全局共享一个类时主要采用的方式。
http://blog.csdn.net/cocoa_geforce/article/details/6747595
5delegate

主要是要把共享的数据设置为XXDelegate的一个成员变量;

然后在需要的地方通过如下方法获得一个XXDelegate的对象,如下:

XXDelegate*app = (XXDelegate *) [[UIApplicationsharedApplicationdelegate];

每次获取delegate并不是创建一个新app,每个app只有一个delegate

6 NSNotification (观察者模式)


7 对象的property属性传值


8 方法的参数传值


9 静态方法传值


10 用给 指向 指针的指针 赋值 的方式传值


11
(待续。。)

转载于:https://www.cnblogs.com/yingkong1987/p/3334125.html

2017-04-21 14:19:48 cherish_joy 阅读数 5889

关于iOS和Unity交互的方法,进行简单的梳理.

调用方法一:

  • Unity调方法传参,有返回值.
    Unity代码:
[DllImport("__Internal")]
// 给iOS传string参数,有返回值,返回值通过iOS的return方法返回给Unity
private static extern string getIPv6(string mHost, string mPort)
  • iOS通过return方法,将值返回给Unity
    iOS代码:
/**
 获取IPv6的值,并返回给Unity

 @param mHost 主机名
 @param mPort 端口号
 @return IPv6值
*/
extern "C" const char * getIPv6(const char *mHost, const char *mPort)
{
    // strdup(const char *__s1) 复制mHost字符串,通过Malloc()进行空间分配 
    return strdup(mHost);
}

注意:

  • 1.如果Unity传参为string类型,不执行strdup()方法而使用return mHost方法,导致mHost没有分配内存空间而报错.
    报错信息:
skins(2509,0x1a8e5cb40) malloc: *** error for object 0x16fdc9114: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
  • 2.如果Unity传参为int类型,可以使用return mHost方法.
  • Unity代码:
[DllImport("__Internal")]
// 给iOS传int参数,无返回值,返回值通过iOS的return方法返回给Unity
private static extern int setMyInt(int date);
  • iOS代码:
// 返回int值
extern "C" int setMyInt(int date)
{
    return date;
}
  • 3.Unity方法中参数的变量名为date,在iOS中的extern “C” int setMyInt(int date)方法中设置的参数变量名可以与Unity的相同,设置为date,也可以是a、b、c等自定义参数变量,但是为了代码规范,尽量和Unity参数保持一致.

  • 4.调用DllImport(“”)方法,需要引入命名空间:
    using System.Runtime.InteropServices;

  • 5.extern “C”修饰的变量和函数是按照C语言方式编译和连接的.

调用方法二:

  • Unity调方法传参,无返回值.
    Unity代码:
// 传数据给iOS
[DllImport("__Internal")]
// 给iOS传string参数,无返回值,返回值通过iOS的UnitySendMessage方法返回给Unity
private static extern void setDate(string date);
// 接收iOS的数据
public void GetDate(string date)
{
}
  • iOS调方法,传参给Unity
    iOS代码:
/**
 返回Unity日期

 @param date 日期
 @return 无返回值
 */
extern "C" void setDate(const char *date)
{
    /**
     发送数据给Unity
     @param obj 模型名
     @param method Unity接收iOS数据的方法名
     @param msg 传给Unity的数据
     UnitySendMessage(const char* obj, const char* method, const char* msg);
    */
    UnitySendMessage("PublicGameObject", "GetDate", date);
}

注意

  • iOS通过UnitySendMessage方法返回数据给Unity时,需要传正确的date值,如果UnitySendMessage方法中的第三个参数不是将date作为参数,而是自定义的NSString类,需要做类型转换(Unity中的字符串为string,OC中的字符串为NSString)如下代码:
extern "C" void setDate(const char *date)
{
    NSString *dateStr = @"Hello Word";
    UnitySendMessage("PublicGameObject", "GetDate", [dateStr UTF8String]);
}

以下是全部代码

  • Unity的.cs文件:
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using UnityEngine.UI;

public class Iossdk : MonoBehaviour
{
    // getIPv6方法单独使用,setDate和GetDate配合使用
    public InputField[] ips;

    [DllImport("__Internal")]
    // 给iOS传string参数,有返回值,返回值通过iOS的return方法返回给Unity
    private static extern string getIPv6(string mHost, string mPort)

    [DllImport("__Internal")]
    // 给iOS传string参数,无返回值,返回值通过iOS的UnitySendMessage方法返回给Unity
    private static extern void setDate(string date);

    [DllImport("__Internal")]
    // 给iOS传int参数,无返回值,返回值通过iOS的return方法返回给Unity
    private static extern int setMyInt(int date);

    // 传int参数给iOS
    public void SetMyInt()
    {
      #if UNITY_IPHONE && !UNITY_EDITOR
          int result = setMyInt(int.Parse(ips[1].text));
          Debug.Log(result);
      #else
          Debug.Log(int.Parse(ips[1].text));
      #endif
    }

    // 传string参数给iOS
    public void SetDate()
    {
      #if UNITY_IPHONE && !UNITY_EDITOR
          setDate(ips[0].text);
      #else
          Debug.Log(ips[0].text);
      #endif
    }

    // 接收iOS的数据
    public void GetDate(string date)
    {
      ips[1].text = date;
      Debug.Log(date);
    }

    // 通过主机名和端口号获取IPv6
    public static string GetIPv6(string mHost, string mPort)
    {
      #if UNITY_IPHONE && !UNITY_EDITOR
          string mIPv6 = getIPv6(mHost, mPort);
          return mIPv6;
      #else
          return mHost + " : " + mPort;
      #endif
    }

    // 程序入口1
    public void Click1()
    {
      string s = GetIPv6(ips[0].text, ips[1].text);
      Debug.Log(s);
    }

    // iOS程序入口2 
    public void Click2()
    {
      SetDate();
    }

    // iOS程序入口3 
    public void Click3()
    {
     SetMyInt();
    }
}
  • iOS代码 :

  • .h文件

#import <Foundation/Foundation.h>

@interface IOSToUnity : NSObject

@end
  • .m文件
#import "IOSToUnity.h"

@implementation IOSToUnity

/**
 获取IPv6的值,并返回给Unity

 @param mHost 主机名
 @param mPort 端口号
 @return IPv6值
*/
extern "C" const char * getIPv6(const char *mHost, const char *mPort)
{
    // strdup(const char *__s1) 复制mHost字符串,通过Malloc()进行空间分配 
    return strdup(mHost);
}

/**
 返回Unity日期

 @param date 日期
 @return 无返回值
*/
extern "C" void setDate(const char *date)
{
    /**
     发送数据给Unity
     @param obj 模型名
     @param method Unity接收iOS数据的方法名
     @param msg 传给Unity的数据
     UnitySendMessage(const char* obj, const char* method, const char* msg);
    */
    UnitySendMessage("PublicGameObject", "GetDate", date);
}

/**
 返回int值

 @param mHost 主机名
 @return 主机名
*/
extern "C" int setMyInt(int date)
{
    return date;
}

@end

如果已经掌握本文参数传递的方法,不妨看下iOS和Unity交互之界面跳转.


简书

iOS和Unity交互之参数传递

个人博客

iOS和Unity交互之参数传递

2017-03-10 11:27:42 shi520fu 阅读数 1727

#pragma mark - 反向传值

1.代理

//主动方(第二个界面):1.创建协议及协议方法 2.设置一个代理属性 3.判断代理是否存在以及协议方法时候存在,然后再传值

//被动方:1.遵守协议 2.设置代理 3. 实现代理方法

@protocol ShowTextDelegate <NSObject>


@required

-(void)showText:(NSString *)text;

@optional

-(UIColor *)showTextOne:(NSString *)text;


@end


@interface SecodViewController : UIViewController


@property (nonatomic,assign)id<ShowTextDelegate> delegate;


@end


//调用代理方法

//判断代理存在,且代理方法有响应

if (_delegate && [_delegate respondsToSelector:@selector(showText:)]) {

    UIColor *color =[_delegate showTextOne:textField.text];

    self.view.backgroundColor = color;

}


@interface RootViewController ()<ShowTextDelegate>

//建立代理关系

svc.delegate = self;

//实现代理方法

-(UIColor *)showTextOne:(NSString *)text

{

    // 找到显示文字的label

    UILabel *label = (id)[self.view viewWithTag:10];

    label.text = text;

    return [UIColor greenColor];

}


//主动方

1.@property (nonatomic ,assign)id delegate;

2.[self.delegate setValue.btn.currentTitle forKey:@"viewCtrTitle"];

//被动方

1.@property (nonatomic,copy) NSString *viewCtrTitle;

2.svc.delegate = self;


3.self.navigationitem.title = viewCtrTitle;


2.block

@property (nonatomic,copy)void(^block)(NSString *text);

//2.SecodViewController要传递文字,它是需要声明block的一方

//3.SecodViewController它声明,它调用 (这样才能传过去一个数,才叫反向传值)

//4.声明一个属性,指向要调用的block


/*

 1.驱动方声明一个block属性 驱动方调用block,执行block中得代码

 2.被动方要具体实现block<驱动的block属性应该指向被动方实现的block>


 */

if (_block) {

    

    _block(textField.text);

}


//1.实现显示文字的功能,也就是它需要完成block的实现部分 这是第一个控制器的内容


SecodViewController *svc = [[SecodViewController alloc]init];


UILabel *label = (id)[self.view viewWithTag:10];


void(^aBlock)(NSString *text) = ^(NSString *text){

    label.text = text;

};


//声明的block指向实现的block

svc.block = aBlock;


#pragma mark - block的基本使用 只有调用block才会实现block中的代码

传入方声明block调用block,接收方实现block对传过来的值进行使用

#warining 1.声明block  2.调用block 3.实现block


@implementation RootViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    //1.block的声明

    

    //声明一个名字为blockNameblock变量

    //-(void)funcName:(BOOL)value

    

    void(^blockName)(BOOL value,NSString *str); (这句话blockName是名字,其余的是类型)

    //2.block赋值

    blockName = ^(BOOL va1,NSString * str1){     (这是给block赋值)

        NSLog(@"%d,%@",va1,str1);

    };

    //也可以把这一步和上一步合起来写,就是声明并且赋值

    void(^blockName)(BOOL value,NSString *str) = ^(BOOL va1,NSString * str1){     (这是给block赋值)

        NSLog(@"%d,%@",va1,str1);

    };


    blockName(YES,@"调用block");                   (这是调用block)

    //声明一个带返回值的block,并给它赋值

    

    __unsafe_unretained RootViewController *rvc =self;

    NSString *(^block2)(UIColor * color) =^(UIColor * colorValue){

        

        rvc.view.backgroundColor = colorValue;

        return@"用来返回的字符串";

        

    };

    

    NSString *str = block2([UIColor greenColor]);

    NSLog(@"block返回的字符串====%@",str);

    

    //3:block作为参数

    

    void(^useBlock)(BOOL value) = ^(BOOL value)

    {

        if (value ==YES) {

            

            NSLog(@"作为参数的block");

        }

    };

    

    [self useAblock:useBlock];

    /*

     [self useAblock:^(BOOL value) {

     if (value == YES) {

     

     NSLog(@"作为参数的block");

     }

     }];

     */

    -(void)useAblock:(void(^)(BOOL value))block

    {

        if (block) {

            NSLog(@"block");

            //如果作为参数的block存在,就调用block

            block(YES);

        }

    }

    //4.block作为返回值

    void(^returnAblock)(BOOL value) = [self returnAblock];

    if (returnAblock) {

        //如果返回的block有值就调用block

        // 调用block

        returnAblock(YES);

    }

    

}


//作为返回值

-(void(^)(BOOL value))returnAblock

{

    return ^(BOOL value){

        

        NSLog(@"作为返回值的block");

    };

}


-(void)viewDidAppear:(BOOL)animated

{

    [super viewDidAppear:animated];

    [self funcName:YES];

}

//函数的实现部分,不调用是不会执行函数中得代码的,调用才执行

-(void)funcName:(BOOL)value

{

    NSLog(@"调用函数");

}


#pragma mark - block的本质

需要注意防止循环引用,使用__weak关键词修饰

void test5();


int main(int argc,const char * argv[])

{

    test5();

    return0;

}


int num = 10;

void test5()

{

    void (^block)() = ^{

        // block内部能够一直引用全局变量

        NSLog(@"----num=%d", num);

    };

    

    num = 20;

    

    block();

}


void test4()

{

    staticint age = 10;

    void (^block)() = ^{

        // block内部能够一直引用被static修饰的变量

        NSLog(@"----age=%d", age);

    };

    

    age = 20;

    

    block();

}


void test3()

{

    __blockint age = 10;

    void (^block)() = ^{

        // block内部能够一直引用被__block修饰的变量

        

        NSLog(@"----age=%d", age);

    };

    

    age = 20;

    

    block();

}


void test2()

{

    int age =10;

    void (^block)() = ^{

        // 普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变

        //因为block不知道这个变量什么时候被销毁,所以直接把变量的值放到那个位置,不管以后变量的死活了,但是全局变量,被static修饰的变量,被_block修饰的变量可以一直引用,就是可以跟踪变量的变化

        NSLog(@"----age=%d", age);

    };

    

    age = 20;

    

    block();

}


void test()

{

    int age =10;

    void (^block)() = ^{

        // ----age=10

        NSLog(@"----age=%d", age);

    };

    block();

}


#pragma mark - block 传值

//2.block

@property (nonatomic, copy)void(^block)(NSString *text);

//2.SecodViewController要传递文字,它是需要声明block的一方

//3.SecodViewController它声明,它调用 (这样才能传过去一个数,才叫反向传值)

//4.声明一个属性,指向要调用的block


/*

 1.驱动方声明一个block属性 驱动方调用block,执行block中得代码

 2.被动方要具体实现block<驱动的block属性应该指向被动方实现的block>

 

 */

if (_block) {

    

    _block(textField.text);

}

//下面这代码在第一个控制器里面

//1.实现显示文字的功能,也就是它需要完成block的实现部分


SecodViewController *svc = [[SecodViewController alloc]init];


UILabel *label = (id)[self.view viewWithTag:10];


void(^aBlock)(NSString *text) = ^(NSString *text){

    label.text = text;

};


//声明的block指向实现的block

svc.block = aBlock;


3.通知

//   创建一个通知


//第一种:创建通知的方法

//A :携带对象

//1.通知的名字

//2.  通知携带的对象

//3.通知携带的信息

/*

 NSNotification *notify = [[NSNotification alloc]initWithName:@"ShowText" object:textField userInfo:nil];

 */

//    B:携带信息

//

//    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:textField.text forKey:@"text"];

//    NSNotification *notify1 = [[NSNotification alloc]initWithName:@"showtext" object:nil userInfo:infoDict];


//获取通知中心

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

//    [nc postNotification:notify];

//    [nc postNotification:notify1];


//第二种,创建并发送一个携带对象的通知

[nc postNotificationName:@"ShowText" object:textField.text];


//第三种,通知中创建一个携带对象或携带信息的通知并发送

[nc postNotificationName:@"ShowText" object:textField.text userInfo:[NSDictionary dictionaryWithObjectsAndKeys:textField.text,@"text",nil]];


//获取通知中心

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

[nc addObserver:self selector:@selector(ShowFunc:) name:@"showtext" object:nil];


-(void)ShowFunc:(NSNotification *)notify

{

    //获取通知携带的信息

    NSDictionary *infoDict = notify.userInfo;

    UILabel *label = (id)[self.view viewWithTag:10];

    label.text = [infoDict objectForKey:@"text"];

}


-(void)dealloc

{

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    [nc removeObserver:self name:@"ShowText" object:nil];

    //[nc removeObserver:self];移除所有通知

}

总结:通知中心发送通知,通知中心接受通知,通知中心移除观察者


4.利用KVC传值

(在下一个界面设置上一个界面的属性值)kvc的传值方法和正向传值的方法原理都是一样的


注意:下面的用单例和全局变量传值基本上不适用知道就好了


5.单例

//(1.AppDelegate)

//保存输入的文字,保存到AppDelegate对象的属性

AppDelegate *del = [UIApplication sharedApplication].delegate;

del.text = textField.text;


//整个应用程序有一个单例对象UIApplication的对象,也只有一个代理,AppDelegate的对象也只有一个

AppDelegate *del = [UIApplication sharedApplication].delegate;

UILabel *label = (id)[self.view viewWithTag:10];

//读取单例属性存储的文字

label.text = del.text;


//(2.自定义一个单例)

//创建单例


//获取单例对象

SingleTon *single = [SingleTon shareSingleTon];

//用单例的属性保存输入的文字

single.text = textField.text;


//获取单例对象

SingleTon *single = [SingleTon shareSingleTon];

UILabel *label = (id)[self.view viewWithTag:10];

//读取单例对象的属性值

label.text = single.text;


6.全局变量

//声明一个全局变量

NSString *text;


//用全局变量去保存输入的文字

text = textField.text;


//说明text在别的文件声明的

extern NSString *text;


UILabel *label = (id)[self.view viewWithTag:10];

label.text = text;



IOS 七种传值方法

阅读数 361