精华内容
参与话题
问答
  • 今天来总结下 nullable, nonnull, __nullable, __nonnull, _Nullable, __Nonnull 之间的区别。 作用 首先, nonnull, __nonnull, __Nonnull 这三个修饰的参数是不可以为nil的。如果参数被它们修饰, 且传入的实参....

    在苹果自己的API中, 我们也见过许多的参数的修饰符, 比如说在方法中修饰参数可否为空的标识。今天来总结下 nullable, nonnull, __nullable, __nonnull, _Nullable, __Nonnull 之间的区别。

    作用

    首先, nonnull, __nonnull, __Nonnull 这三个修饰的参数是不可以为nil的。如果参数被它们修饰, 且传入的实参为nil的话, 编译器将会产生警告。
    nullable, __nullable, _Nullable 这三个修饰的参数是可以为nil的。如果参数被它们修饰, 且传入的实参为nil的话, 编译器也不会产生警告。

    用法

    // string 可以为 nil
    - (void)methodWithString:(nullable NSString *)string {}
    // string 不可以为 nil
    - (void)methodWithString:(nonnull NSString *)string {}
    

    nullable__nullable_Nullable 的区别联系

    nullable__nullable_Nullablenonnull__nonnull__Nonnull 其实是成对的, 所以这里只介绍前者, 后者用法与前者一致。

    先来看一段代码, 可以考虑下它们之间的区别是什么。

    @property (nonatomic, copy, nullable) NSString *string1;
    @property (nonatomic, copy) NSString * _Nullable string2;
    @property (nonatomic, copy) NSString * __nullable string3;
    
    - (void)methodWithString1:(nullable NSString *)string {}
    - (void)methodWithString2:(NSString * _Nullable)string {}
    - (void)methodWithString3:(NSString * __nullable)string {}
    

    其实呢, 这三种写法的效果都是一样的,只是代码摆放的位置不同。
    苹果在 Xcode 6.3 引入了一个 Objective-C 的新特性: Nullability Annotations ,它的核心是两个修饰: __nullable__nonnull 。在 Xcode 7 中,为了避免与第三方库潜在的冲突,苹果把 __nonnull__nullable 改成 _Nonnull_Nullable 。而且苹果也支持没有下划线的写法 nonnullnullable ,于是就三种写法都可以使用的情况。

    从上面的代码可以看出, nullable 修饰于类型前, 但__nullable_Nullable 却修饰于类型后。

    那么它们还有其他的区别呢?
    对于方法参数、方法返回值、属性的修饰,可以使用:nonnullnullable 或者 _Nonnull_Nullable 或者 __nonnull__nullable
    对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull_Nullable 或者 __nonnull__nullable 。但是根据苹果的API来说建议弃用__nonnull__nullable

    所以应该按照下面的代码来写:

    // C函数
    - (void)methodWithError1:(NSError * _Nullable * _Nullable)error {}
    // Block 返回值
    - (void)methodWithBlock1:(void(^ _Nullable)(void))block {}
    - (void)methodWithBlock2:(void(^ __nullable)(void))block {}
    // 注意下面的 nullable 用于修饰传入的参数 block 可以为空,而不是修饰 block 返回值
    - (void)methodWithBlock3:(nullable void(^)(void))block {}
    
    // Block返回值 和 Block参数
    - (void)methodWithBlock4:(NSString * __nonnull(^ __nullable)(NSString * __nullable params))block {}
    - (void)methodWithBlock5:(NSString * _Nonnull (^ _Nullable)(NSString * _Nullable params))block {}
    // 注意下面的 nullable 用于修饰方法传入的参数 block 可以为空,而 __nonnull 用于修饰 block 返回值 NSString 不能为空;
    - (void)methodWithBlock6:(nullable NSString * __nonnull(^)(NSString * __nullable params))block {}
    

    拓展 Nonnull Audited Regions

    有两个宏 NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END 。在这两个宏之间的代码,所有简单指针对象都被认为是 nonnull 修饰的 ,所以我们只需要指定 nullable 的指针对象即可。

    NS_ASSUME_NONNULL_BEGIN
    
    - (void)methodWithString4:(NSString *)str string:(nullable NSString *)string {}
    
    NS_ASSUME_NONNULL_END
    

    如上写的话, 参数strnonnull的, 而参数stringnullable 的。

    总结

    对于方法参数、方法返回值、属性的修饰,可以使用:nonnullnullable 或者 _Nonnull_Nullable 或者 __nonnull__nullable
    对于 C函数的参数、Block的参数、Block返回值的修饰,只能使用: _Nonnull_Nullable 或者 __nonnull__nullable 。但是根据苹果的API来说建议弃用__nonnull__nullable

    Demo下载地址:
    Demo
    参考资料:
    Difference between nullable, __nullable and _Nullable in Objective-C

    展开全文
  • Nonnull annot etc

    2020-12-09 14:01:01
    <div><p>more Nonnull annotations in jmrix, managers, javadoc fixes</p><p>该提问来源于开源项目:JMRI/JMRI</p></div>
  • NonNull annotation issue

    2020-12-26 04:33:12
    <p>NonNull annotation is not working properly on Fields with annotation. But its working fine with DSL's annotation. <p>import com.dslplatform.json.<em>; import com.dslplatform.json.NonNull; ...
  • Objects::nonNull

    2020-11-29 20:18:50
    <p>with a method reference to <code>Objects::nonNull</code>. However, this won't work for older Android versions as it's dependent on a certain SDK level (24). <p>Could the method therefore be...
  • nonnull和nullable

    2018-03-14 14:36:12
    1,nonnull和nullable声明属性是否可以为nil,如果对nonnull属性赋值为nil,则会报警告。123@property (nonatomic, strong, nonnull) NSArray *array1;@property (nonatomic, strong) NSArray * __nullable array2;...
    1,nonnull和nullable
    声明属性是否可以为nil,如果对nonnull属性赋值为nil,则会报警告。
    1
    2
    3
    @property (nonatomic, strong, nonnull) NSArray *array1;

    @property (nonatomic, strong) NSArray * __nullable array2;
    作用主要是开发者之间交互,调用属性时可以知道这个属性是可能为nil的,针对这个状态做些处理。
    默认情况下就是nullable状态。
    可以用来给方法的参数最要求,比如定一个方法,参数为一个不为空的对象:
     
    2,null_resettable
    声明属性set方法可以为nil,但是get一定不能为nil,这里有一个貌似冲突的地方,就是可以定义个属性为nil,但是在获取这个属性的时候,这个属性不能为nil,否则会有警告。
     
    这里用到的地方例如在UIViewController中的view,意味着开发者可以对控制器的view清空赋值为nil,但是控制器view是懒加载的,每次获取控制器的view时候,都可以再获取到非nil的view。
     
    一个Objective-C的新特性:nullability annotations。这一新特性的核心是两个新的类型注释:__nullable__nonnull从字面上我们可以猜到,__nullable表示对象可以是NULL或nil,而__nonnull表示对象不应该为空。当我们不遵循这一规则时,编译器就会给出警告。
    不过这只是一个警告,程序还是能编译通过并运行。
    事实上,在任何可以使用const关键字的地方都可以使用__nullable和__nonnull,不过这两个关键字仅限于使用在指针类型上。而在方法的声明中,我们还可以使用不带下划线的nullable和nonnull
    展开全文
  • How to deal with NonNull

    2021-01-02 04:47:40
    s the proper way to deal with <code>NonNull<T></code> not being <code>T</code>? Let's assume that you have a resolver like: <pre><code> public async Task<nonnull>>>> AllXs(.....
  • Lombok之@NonNull使用

    千次阅读 2019-10-15 15:06:48
    为什么要用@NonNull?二. @NonNull如何使用?三. @NonNull源码四. 特别说明 一. 为什么要用@NonNull? 二. @NonNull如何使用? 三. @NonNull源码 四. 特别说明 本文已经收录在Lombok注解系列文章总览中,并继承上文中...

    一. 为什么要用@NonNull?

    NullPointerException空指针异常(俗称NPE异常)可以说是每一个开发者都遇到过的一个常见异常,即使是经验丰富的老手,也会在一不留神的写出NPE的bug。指针只存在于c语言中,Java中是没有指针的,空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除去静态),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常。
    新建Student类,并创建全参构造函数,getter和setter方法。

    public class Student {
    
        private String name;
    
        private Integer age;
    
        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    

    示例代码
    我们new了一个name为null,age为18的student对象。可以看到当程序通过student.getName()访问name变量后,再调用String的实例方法length(),控制台抛出了NullPointerException异常。这是因为name的变量值为null,所以报NPE异常。解决这类问题的办法,我们可以在取出name值后进行判空操作,但是这样每次取name值都要进行判空操作,很是麻烦。我们可以在构造函数中要求name值非空:

       public Student(String name, Integer age) {
            if (name == null) {
                throw new NullPointerException("name is null");
            } else {
                this.name = name;
                this.age = age;
            }
        }
    

    这样一来,我们在new的时候就会提前发现错误。new的时候就会报NullPointerException,避免后面的空指针异常。new时候的空指针异常是不可能避免的,这是由于Java中规定null可以为任何包装类型的变量赋值。这个判空的逻辑体可以使用Lombok的注解@NonNull进行简化代码。

    二. @NonNull如何使用?

    在个构造函数的参数加上@NonNull后,便会自动对该参数值进行判空。

     public Student(@NonNull String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    

    编译该工程,打开编译后的文件。可以看到,编译器已经为形参name生成了判空的代码。
    student.class

    三. @NonNull源码

    package lombok;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * If put on a parameter, lombok will insert a null-check at the start of the method / constructor's body, throwing a
     * {@code NullPointerException} with the parameter's name as message. If put on a field, any generated method assigning
     * a value to this field will also produce these null-checks.
     * 如果放在一个参数上,lombok将在方法/构造函数体的开头插入一个空检查,抛出一个{@code NullPointerException},参数名为message。如果放
     * 在字段(成员变量)上,则生成的任何方法都被赋值该字段的值也将产生这些空值检查。
     */
    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.CLASS)
    @Documented
    public @interface NonNull {
    }
    
    

    四. 特别说明

    本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明。
    源码地址:gitee

    展开全文
  • Objective-C为了和Swift兼容,每个属性或每个...苹果为了减轻我们的工作量,定义了NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END两个宏。 在这两个宏之间的所有简单指针对象都被假定为nonnull。我们只需要指定...

    原文:https://www.jianshu.com/p/a197705a44e9

    Objective-C为了和Swift兼容,每个属性或每个方法都去指定nonnullnullable。

    苹果为了减轻我们的工作量,定义了NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END两个宏。

    在这两个宏之间的所有简单指针对象都被假定为nonnull。我们只需要指定那些nullable的指针

    转载于:https://www.cnblogs.com/liuyongfa/p/10185084.html

    展开全文
  • Some nonnull/nullable issues

    2021-01-07 04:51:42
    <div><p>Please rebuild this project with xcode 8. It trows some errors with nonnull/nullable redefinitions.</p><p>该提问来源于开源项目:core-plot/core-plot</p></div>
  • NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END 作用 这两个东西是Nonnull区域设置(Audited Regions) 。 这两个宏之间的代码里的所有简单指针对象都被默认为 ___nonnull,我们只需要去指定 __nullable 的指针。 ...
  • That means we could always assert, if an attribute is marked as <code>nonnull</code> or if <code>RMAssumeNonnull</code> is enabled and the attribute isn't marked as <code>nullable</code>. <p>But ...
  • <div><p>I only replaced org.eclipse.jdt.annotation.NonNull with android.support.annotation.NonNull if the superclasses already have an android.support.annotation.NonNull annotation, but maybe it'...
  • define void (i8* nonnull %p) { ; Can %p be poison? } </code></pre> <p>I think %p cannot be poison because it is UB for a caller to pass a poison value as a nonnull argument. If it is well-defined ...
  • Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END...
  • Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END...
  • thread: use NonNull<>

    2020-12-09 04:42:40
    <div><p>Use NonNull to ensure pointers are not NULL when dealing with FFI. </p><p>该提问来源于开源项目:openebs/Mayastor</p></div>
  • <div><p>This feels marginally safer and the combination of NonNull and inlines yield a small performance improvement in a library I have.</p><p>该提问来源于开源项目:PyO3/pyo3</p></div>
  • <div><p>I think <code>NonNull</code> should be enforced at two locations: 1) <a href="https://github.com/graphql-python/graphene-django/blob/master/graphene_django/converter.py#L190">Here, <code>...
  • NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END

    千次阅读 2016-08-18 16:38:34
    NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END
  • 升级成 Xcode 10 之后每次 New File 看到 .h 基本都能看到 NS_ASSUME_NONNULL_BEGIN 和 NS_ASSUME_NONNULL_END 成对出现在 @interface 与 @end 上下, 包裹住它, 这两对关键字并非新特性, 只是 Xcode 10 之后系统默.....
  • <div><p><code>NonNull</code> has the same variance as *const, but also enables niche layout optimizations for things like <code>Option<Bucket<T>></code>.</p><p>该提问来源于开源项目:...
  • Nonnull区域设置(Audited Regions)  如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END...
  • 最近使用新更新的Xcode10.0新建类时,发现它自动为我们在.h文件里添加了NS_ASSUME_NONNULL_BEGIN和 NS_ASSUME_NONNULL_END。如下示例: #import &lt;UIKit/UIKit.h&gt; NS_ASSUME_NONNULL_BEGIN @...
  • Nonnull区域设置(Audited Regions) 如果需要每个属性或每个方法都去指定nonnull和nullable,是一件非常繁琐的事。苹果为了减轻我们的工作量,专门提供了两个宏:NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。 ...
  • I realized that this porting of python code could be improved (at least according to my taste) by indicating that if a model is given to <code>save</code> it should be nonNull. Then <code>save(model)...

空空如也

1 2 3 4 5 ... 20
收藏数 3,803
精华内容 1,521
关键字:

nonnull